home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gamers Delight 2
/
Gamers Delight 2.iso
/
Aminet
/
game
/
role
/
Ang261Lib.lha
/
src
/
misc1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-10-22
|
149KB
|
6,026 lines
/*
* Misc1.c: misc utility and initialization code, magic objects code
*
* Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
*
* This software may be copied and distributed for educational, research, and
* not for profit purposes provided that this copyright and statement are
* included in all such copies.
*/
#ifndef FSCALE
#define FSCALE (1<<8)
#endif
#if defined(Pyramid) || defined(NeXT) || defined(sun) || \
defined(NCR3K) || defined(linux) || defined(ibm032) || defined (__osf__)
#include <sys/time.h>
#else
#include <time.h>
#endif
#if !defined(GEMDOS) && !defined(MAC)
#ifndef VMS
#include <sys/types.h>
#else
#include <types.h>
#endif
#endif
#include <stdio.h>
#include "constant.h"
#include "monster.h"
#include "config.h"
#include "types.h"
#include "externs.h"
#ifdef USG
#ifndef ATARIST_MWC
#include <string.h>
#else
#include "string.h"
#endif
#else
#include <strings.h>
#endif
typedef struct statstime {
int cp_time[4];
int dk_xfer[4];
unsigned int v_pgpgin;
unsigned int v_pgpgout;
unsigned int v_pswpin;
unsigned int v_pswpout;
unsigned int v_intr;
int if_ipackets;
int if_ierrors;
int if_opackets;
int if_oerrors;
int if_collisions;
unsigned int v_swtch;
long avenrun[3];
struct timeval boottime;
struct timeval curtime;
} statstime;
/* Lets do all prototypes correctly.... -CWS */
#ifndef NO_LINT_ARGS
#ifdef __STDC__
static int test_place(int, int);
static char *cap(char *);
static void magic_ammo(inven_type *, int, int, int, int, int);
#else
static int test_place();
static char *cap();
static void magic_ammo();
#endif
static void compact_objects();
#endif
extern int peek;
extern int rating;
/* gets a new random seed for the random number generator */
void
init_seeds()
{
old_state = (char *) malloc(256); /* excellent R.N.G. */
dummy_state = (char *) malloc(8); /* so-so R.N.G., but who cares? -CFT */
/* if malloc choked on 264 bytes, we're dead anyways */
if (!old_state || !dummy_state) {
puts("\nError initializing; unable to malloc space for RNG arrays...\n");
exit(2);
}
/* is 'unix' a std define for unix system? I thought UNIX is more common?
This may need to be changed. It's fine for PCs, anyways... -CFT */
#ifdef unix
/* Grab a random seed from the clock & PID... */
(void) initstate(time(NULL), dummy_state, 8);
(void) initstate(((getpid() << 1) * (time(NULL) >> 3)), old_state, 256);
#else
/* ...else just grab a random seed from the clock. -CWS */
(void) initstate(time(NULL), dummy_state, 8);
(void) initstate(random(), old_state, 256);
#endif /* unix */
town_seed = random();
randes_seed = random();
}
/* change to different random number generator state */
void
set_seed(seed)
int32u seed;
{
setstate(dummy_state);
srandom((seed % 2147483646L) + 1); /* necessary to keep the town/desc's */
} /* the same (legacy from rnd.c) -CWS */
/* restore the normal random generator state */
void
reset_seed()
{
(void)setstate(old_state);
}
#if !defined(time_t)
#define time_t long
#endif
/* Check the day-time strings to see if open -RAK- */
int
check_time()
{
#ifdef CHECKHOURS
time_t c;
register struct tm *tp;
#ifndef __MINT__
struct statstime st;
#endif
c = time((time_t *)0);
tp = localtime(&c);
if (days[tp->tm_wday][tp->tm_hour + 4] != 'X') {
return FALSE;
}
#if !(defined(__MINT__) || defined(NCR3K) || defined(linux) \
|| defined(__386BSD__) || defined (__osf__))
else {
if (!rstat("localhost", &st)) {
if (((int)((double)st.avenrun[2] / (double)FSCALE)) >= (int)LOAD)
return FALSE;
}
}
#endif /* MINT, etc */
#endif /* CHECKHOURS - [cjh] */
return TRUE;
}
#ifdef RI
/* Generates a random integer x where 1<=X<=MAXVAL -RAK- */
int
randint(maxval)
int maxval;
{
register long randval;
if (maxval < 1)
return 1;
randval = random();
return ((randval % maxval) + 1);
}
#endif
/* Generates a random integer number of NORMAL distribution -RAK- */
int
randnor(mean, stand)
int mean, stand;
{
register int tmp, offset, low, iindex, high;
tmp = randint(MAX_SHORT);
/* off scale, assign random value between 4 and 5 times SD */
if (tmp == MAX_SHORT) {
offset = 4 * stand + randint(stand);
/* one half are negative */
if (randint(2) == 1)
offset = (-offset);
return (mean + offset);
}
/* binary search normal normal_table to get index that matches tmp */
/* this takes up to 8 iterations */
low = 0;
iindex = NORMAL_TABLE_SIZE >> 1;
high = NORMAL_TABLE_SIZE;
while (TRUE) {
if ((normal_table[iindex] == tmp) || (high == (low + 1)))
break;
if (normal_table[iindex] > tmp) {
high = iindex;
iindex = low + ((iindex - low) >> 1);
} else {
low = iindex;
iindex = iindex + ((high - iindex) >> 1);
}
}
/* might end up one below target, check that here */
if (normal_table[iindex] < tmp)
iindex = iindex + 1;
/* normal_table is based on SD of 64, so adjust the index value here, round
* the half way case up
*/
offset = ((stand * iindex) + (NORMAL_TABLE_SD >> 1)) / NORMAL_TABLE_SD;
/* one half should be negative */
if (randint(2) == 1)
offset = (-offset);
return (mean + offset);
}
/* Returns position of first set bit -RAK- */
/* and clears that bit */
int
bit_pos(test)
int32u *test;
{
register int i;
register int32u mask = 0x1L;
for (i = 0; i < sizeof(*test) * 8; i++) {
if (*test & mask) {
*test &= ~mask;
return (i);
}
mask <<= 0x1L;
}
/* no one bits found */
return (-1);
}
/* Calculates current boundaries -RAK- */
void
panel_bounds()
{
panel_row_min = panel_row * (SCREEN_HEIGHT / 2);
panel_row_max = panel_row_min + SCREEN_HEIGHT - 1;
panel_row_prt = panel_row_min - 1;
panel_col_min = panel_col * (SCREEN_WIDTH / 2);
panel_col_max = panel_col_min + SCREEN_WIDTH - 1;
panel_col_prt = panel_col_min - 13;
}
/* Given an row (y) and col (x), this routine detects -RAK- */
/*
* when a move off the screen has occurred and figures new borders. Force
* forcses the panel bounds to be recalculated, useful for 'W'here.
*/
int
get_panel(y, x, force)
int y, x, force;
{
register int prow, pcol;
register int panel;
prow = panel_row;
pcol = panel_col;
if (force || (y < panel_row_min + 2) || (y > panel_row_max - 2)) {
prow = ((y - SCREEN_HEIGHT / 4) / (SCREEN_HEIGHT / 2));
if (prow > max_panel_rows)
prow = max_panel_rows;
else if (prow < 0)
prow = 0;
}
if (force || (x < panel_col_min + 3) || (x > panel_col_max - 3)) {
pcol = ((x - SCREEN_WIDTH / 4) / (SCREEN_WIDTH / 2));
if (pcol > max_panel_cols)
pcol = max_panel_cols;
else if (pcol < 0)
pcol = 0;
}
if ((prow != panel_row) || (pcol != panel_col)) {
panel_row = prow;
panel_col = pcol;
panel_bounds();
panel = TRUE;
/* stop movement if any */
if (find_bound)
end_find();
} else
panel = FALSE;
return (panel);
}
/* Distance between two points -RAK- */
int
distance(y1, x1, y2, x2)
int y1, x1, y2, x2;
{
register int dy, dx;
dy = y1 - y2;
if (dy < 0)
dy = (-dy);
dx = x1 - x2;
if (dx < 0)
dx = (-dx);
return ((((dy + dx) << 1) - (dy > dx ? dx : dy)) >> 1);
}
/* Checks points north, south, east, and west for a wall -RAK- */
/*
* note that y,x is always in_bounds(), i.e. 0 < y < cur_height-1, and 0 < x
* < cur_width-1
*/
int
next_to_walls(y, x)
register int y, x;
{
register int i;
register cave_type *c_ptr;
i = 0;
c_ptr = &cave[y - 1][x];
if (c_ptr->fval >= MIN_CAVE_WALL)
i++;
c_ptr = &cave[y + 1][x];
if (c_ptr->fval >= MIN_CAVE_WALL)
i++;
c_ptr = &cave[y][x - 1];
if (c_ptr->fval >= MIN_CAVE_WALL)
i++;
c_ptr = &cave[y][x + 1];
if (c_ptr->fval >= MIN_CAVE_WALL)
i++;
return (i);
}
/* Checks all adjacent spots for corridors -RAK- */
/*
* note that y, x is always in_bounds(), hence no need to check that j, k are
* in_bounds(), even if they are 0 or cur_x-1 is still works
*/
int
next_to_corr(y, x)
register int y, x;
{
register int k, j, i;
register cave_type *c_ptr;
i = 0;
for (j = y - 1; j <= (y + 1); j++)
for (k = x - 1; k <= (x + 1); k++) {
c_ptr = &cave[j][k];
/* should fail if there is already a door present */
if (c_ptr->fval == CORR_FLOOR
&& (c_ptr->tptr == 0 || t_list[c_ptr->tptr].tval < TV_MIN_DOORS))
i++;
}
return (i);
}
/* generates damage for 2d6 style dice rolls */
int
damroll(num, sides)
int num, sides;
{
register int i, sum = 0;
for (i = 0; i < num; i++)
sum += randint(sides);
return (sum);
}
int
pdamroll(array)
int8u *array;
{
return damroll((int)array[0], (int)array[1]);
}
/*
* A simple, fast, integer-based line-of-sight algorithm. By Joseph Hall,
* 4116 Brewster Drive, Raleigh NC 27606. Email to jnh@ecemwl.ncsu.edu.
*
* Returns TRUE if a line of sight can be traced from x0, y0 to x1, y1.
*
* The LOS begins at the center of the tile [x0, y0] and ends at the center of
* the tile [x1, y1]. If los() is to return TRUE, all of the tiles this line
* passes through must be transparent, WITH THE EXCEPTIONS of the starting
* and ending tiles.
*
* We don't consider the line to be "passing through" a tile if it only passes
* across one corner of that tile.
*/
/*
* Because this function uses (short) ints for all calculations, overflow may
* occur if deltaX and deltaY exceed 90.
*/
int
los(fromY, fromX, toY, toX)
int fromY, fromX, toY, toX;
{
register int tmp, deltaX, deltaY;
deltaX = toX - fromX;
deltaY = toY - fromY;
/* Adjacent? */
if ((deltaX < 2) && (deltaX > -2) && (deltaY < 2) && (deltaY > -2))
return TRUE;
/* Handle the cases where deltaX or deltaY == 0. */
if (deltaX == 0) {
register int p_y; /* y position -- loop variable */
if (deltaY < 0) {
tmp = fromY;
fromY = toY;
toY = tmp;
}
for (p_y = fromY + 1; p_y < toY; p_y++)
if (cave[p_y][fromX].fval >= MIN_CLOSED_SPACE)
return FALSE;
return TRUE;
} else if (deltaY == 0) {
register int px; /* x position -- loop variable */
if (deltaX < 0) {
tmp = fromX;
fromX = toX;
toX = tmp;
}
for (px = fromX + 1; px < toX; px++)
if (cave[fromY][px].fval >= MIN_CLOSED_SPACE)
return FALSE;
return TRUE;
}
/* handle Knightlike shapes -CWS */
if (MY_ABS(deltaX) == 1) {
if (deltaY == 2) {
if (cave[fromY + 1][fromX].fval <= MAX_OPEN_SPACE)
return TRUE;
} else if (deltaY == (-2)) {
if (cave[fromY - 1][fromX].fval <= MAX_OPEN_SPACE)
return TRUE;
}
} else if (MY_ABS(deltaY) == 1) {
if (deltaX == 2) {
if (cave[fromY][fromX + 1].fval <= MAX_OPEN_SPACE)
return TRUE;
} else if (deltaX == (-2)) {
if (cave[fromY][fromX - 1].fval <= MAX_OPEN_SPACE)
return TRUE;
}
}
/*
* Now, we've eliminated all the degenerate cases. In the computations below,
* dy (or dx) and m are multiplied by a scale factor, scale = abs(deltaX *
* deltaY * 2), so that we can use integer arithmetic.
*/
{
register int px, /* x position */
p_y, /* y position */
scale2;/* above scale factor / 2 */
int scale, /* above scale factor */
xSign, /* sign of deltaX */
ySign, /* sign of deltaY */
m; /* slope or 1/slope of LOS */
scale2 = MY_ABS(deltaX * deltaY);
scale = scale2 << 1;
xSign = (deltaX < 0) ? -1 : 1;
ySign = (deltaY < 0) ? -1 : 1;
/*
* Travel from one end of the line to the other, oriented along the
* longer axis.
*/
if (MY_ABS(deltaX) >= MY_ABS(deltaY)) {
register int dy;/* "fractional" y position */
/*
* We start at the border between the first and second tiles, where
* the y offset = .5 * slope. Remember the scale factor. We have:
*
* m = deltaY / deltaX * 2 * (deltaY * deltaX) = 2 * deltaY * deltaY.
*/
dy = deltaY * deltaY;
m = dy << 1;
px = fromX + xSign;
/* Consider the special case where slope == 1. */
if (dy == scale2) {
p_y = fromY + ySign;
dy -= scale;
} else
p_y = fromY;
while (toX - px) {
if (cave[p_y][px].fval >= MIN_CLOSED_SPACE)
return FALSE;
dy += m;
if (dy < scale2)
px += xSign;
else if (dy > scale2) {
p_y += ySign;
if (cave[p_y][px].fval >= MIN_CLOSED_SPACE)
return FALSE;
px += xSign;
dy -= scale;
} else {
/*
* This is the case, dy == scale2, where the LOS exactly
* meets the corner of a tile.
*/
px += xSign;
p_y += ySign;
dy -= scale;
}
}
return TRUE;
} else {
register int dx;/* "fractional" x position */
dx = deltaX * deltaX;
m = dx << 1;
p_y = fromY + ySign;
if (dx == scale2) {
px = fromX + xSign;
dx -= scale;
} else
px = fromX;
while (toY - p_y) {
if (cave[p_y][px].fval >= MIN_CLOSED_SPACE)
return FALSE;
dx += m;
if (dx < scale2)
p_y += ySign;
else if (dx > scale2) {
px += xSign;
if (cave[p_y][px].fval >= MIN_CLOSED_SPACE)
return FALSE;
p_y += ySign;
dx -= scale;
} else {
px += xSign;
p_y += ySign;
dx -= scale;
}
}
return TRUE;
}
}
}
/* Returns symbol for given row, column -RAK- */
unsigned char
loc_symbol(y, x)
int y, x;
{
register cave_type *cave_ptr;
register struct flags *f_ptr;
cave_ptr = &cave[y][x];
f_ptr = &py.flags;
if ((cave_ptr->cptr == 1) && (!find_flag || find_prself))
return '@';
if (f_ptr->status & PY_BLIND)
return ' ';
if ((f_ptr->image > 0) && (randint(12) == 1))
return randint(95) + 31;
if ((cave_ptr->cptr > 1) && (m_list[cave_ptr->cptr].ml))
return c_list[m_list[cave_ptr->cptr].mptr].cchar;
if (!cave_ptr->pl && !cave_ptr->tl && !cave_ptr->fm)
return ' ';
if ((cave_ptr->tptr != 0)
&& (t_list[cave_ptr->tptr].tval != TV_INVIS_TRAP))
return t_list[cave_ptr->tptr].tchar;
if (cave_ptr->fval <= MAX_CAVE_FLOOR)
return '.';
if (cave_ptr->fval == GRANITE_WALL || cave_ptr->fval == BOUNDARY_WALL
|| highlight_seams == FALSE) {
#ifdef MSDOS
return wallsym;
#else
#ifndef ATARIST_MWC
return '#';
#else
return (unsigned char)240;
#endif
#endif
} else /* Originally set highlight bit, but that is not portable,
* now use the percent sign instead. */
return '%';
}
/* Tests a spot for light or field mark status -RAK- */
int
test_light(y, x)
int y, x;
{
register cave_type *cave_ptr;
cave_ptr = &cave[y][x];
if (cave_ptr->pl || cave_ptr->tl || cave_ptr->fm)
return (TRUE);
else
return (FALSE);
}
/* Prints the map of the dungeon -RAK- */
void
prt_map()
{
register int i, j, k;
register unsigned char tmp_char;
k = 0;
for (i = panel_row_min; i <= panel_row_max; i++) { /* Top to bottom */
k++;
erase_line(k, 13);
for (j = panel_col_min; j <= panel_col_max; j++) { /* Left to right */
tmp_char = loc_symbol(i, j);
if (tmp_char != ' ')
print(tmp_char, i, j);
}
}
}
/* Compact monsters -RAK- */
/*
* Return TRUE if any monsters were deleted, FALSE if could not delete any
* monsters.
*/
int
compact_monsters()
{
register int i;
int cur_dis, delete_any;
register monster_type *mon_ptr;
msg_print("Compacting monsters...");
cur_dis = 66;
delete_any = FALSE;
do {
for (i = mfptr - 1; i >= MIN_MONIX; i--) {
mon_ptr = &m_list[i];
if ((cur_dis < mon_ptr->cdis) && (randint(3) == 1)) {
/* Don't compact Melkor! */
if (c_list[mon_ptr->mptr].cmove & CM_WIN)
/* do nothing */
;
/* in case this is called from within creatures(), this is a
* horrible hack, the m_list/creatures() code needs to be
* rewritten
*/
else if (hack_monptr < i) {
delete_monster(i);
delete_any = TRUE;
} else
/* fix1_delete_monster() does not decrement mfptr, so don't
* set delete_any if this was called
*/
fix1_delete_monster(i);
}
}
if (!delete_any) {
cur_dis -= 6;
/* can't do anything else but abort, if can't delete any monsters */
if (cur_dis < 0)
return FALSE;
}
}
while (!delete_any);
return TRUE;
}
/* Add to the players food time -RAK- */
void
add_food(num)
int num;
{
register struct flags *p_ptr;
register int extra, penalty;
p_ptr = &py.flags;
if (p_ptr->food < 0)
p_ptr->food = 0;
p_ptr->food += num;
if (num > 0 && p_ptr->food <= 0)
p_ptr->food = 32000; /* overflow check */
if (p_ptr->food > PLAYER_FOOD_MAX) {
msg_print("You are bloated from overeating. ");
/* Calculate how much of num is responsible for the bloating. Give the
* player food credit for 1/50, and slow him for that many turns also.
*/
extra = p_ptr->food - PLAYER_FOOD_MAX;
if (extra > num)
extra = num;
penalty = extra / 50;
p_ptr->slow += penalty;
if (extra == num)
p_ptr->food = p_ptr->food - num + penalty;
else
p_ptr->food = PLAYER_FOOD_MAX + penalty;
} else if (p_ptr->food > PLAYER_FOOD_FULL)
msg_print("You are full. ");
}
/* Returns a pointer to next free space -RAK- */
int
popm()
{
if (mfptr == MAX_MALLOC)
if (!compact_monsters())
return (-1);
return (mfptr++);
}
/* Gives Max hit points -RAK- */
int
max_hp(array)
int8u *array;
{
return ((int)(array[0]) * (int)(array[1]));
}
/* Places a monster at given location -RAK- */
int
place_monster(y, x, z, slp)
register int y, x, z;
int slp;
{
register int cur_pos, j, ny,nx,count;
register monster_type *mon_ptr;
char buf[100];
if ((z < 0) || (z >= MAX_CREATURES))
return FALSE; /* another paranoia check -CFT */
if (!test_place(y, x))
return FALSE; /* YA paranoia check -CFT */
if (c_list[z].cdefense & UNIQUE) {
if (u_list[z].exist) {
if (wizard) {
(void)sprintf(buf, "Tried to create %s but exists.", c_list[z].name);
msg_print(buf);
}
return FALSE;
}
if (u_list[z].dead) {
if (wizard) {
(void)sprintf(buf, "Tried to create %s but dead.", c_list[z].name);
msg_print(buf);
}
return FALSE;
}
u_list[z].exist = 1;
}
cur_pos = popm(); /* from um55, paranoia error check... */
if (cur_pos == -1)
return FALSE;
if ((wizard || peek) && (c_list[z].cdefense & UNIQUE))
msg_print(c_list[z].name);
if (c_list[z].level > (unsigned)dun_level) {
int c;
rating += ((c = c_list[z].level - dun_level) > 30) ? 15 : c / 2;
if (c_list[z].cdefense & UNIQUE)
rating += (c_list[z].level - dun_level) / 2;
}
mon_ptr = &m_list[cur_pos];
mon_ptr->fy = y;
mon_ptr->fx = x;
mon_ptr->mptr = z;
if ((c_list[z].cdefense & MAX_HP) || be_nasty)
mon_ptr->hp = max_hp(c_list[z].hd);
else
mon_ptr->hp = pdamroll(c_list[z].hd);
mon_ptr->maxhp = mon_ptr->hp;
mon_ptr->cspeed = c_list[z].speed - 10;
mon_ptr->stunned = 0;
mon_ptr->confused = 0;
mon_ptr->monfear = 0;
mon_ptr->cdis = distance(char_row, char_col, y, x);
mon_ptr->ml = FALSE;
cave[y][x].cptr = cur_pos;
if (slp) {
if (c_list[z].sleep == 0)
mon_ptr->csleep = 0;
else
mon_ptr->csleep = ((int)c_list[z].sleep * 2) +
randint((int)c_list[z].sleep * 10);
} else
/* to give the player a sporting chance, any monster that appears in
line-of-sight and can cast spells or breathe, should be asleep.
This is an extension of Um55's sleeping dragon code... */
if (((c_list[z].spells & (CAUSE_LIGHT|CAUSE_SERIOUS|HOLD_PERSON|
BLINDNESS|CONFUSION|FEAR|SLOW|BREATH_L|
BREATH_G|BREATH_A|BREATH_FR|BREATH_FI|
FIRE_BOLT|FROST_BOLT|ACID_BOLT|MAG_MISS|
CAUSE_CRIT|FIRE_BALL|FROST_BALL|MANA_BOLT))
|| (c_list[z].spells2 & (BREATH_CH|BREATH_SH|BREATH_SD|BREATH_CO|
BREATH_DI|BREATH_LD|LIGHT_BOLT|LIGHT_BALL|
ACID_BALL|TRAP_CREATE|RAZOR|MIND_BLAST|
MISSILE|PLASMA_BOLT|NETHER_BOLT|ICE_BOLT|
FORGET|BRAIN_SMASH|ST_CLOUD|TELE_LEV|
WATER_BOLT|WATER_BALL|NETHER_BALL|BREATH_NE))
|| (c_list[z].spells3 & (BREATH_WA|BREATH_SL|BREATH_LT|BREATH_TI|
BREATH_GR|BREATH_DA|BREATH_PL|ARROW|
DARK_STORM|MANA_STORM)))
&& (los(y,x, char_row, char_col)))
mon_ptr->csleep = randint(4); /* if asleep only to prevent
* summon-breathe-breathe-breathe-die,
* then don't sleep long -CFT */
else mon_ptr->csleep = 0;
update_mon(cur_pos); /* light up the monster if we can see it... -CFT */
/* Unique kobolds, Liches, orcs, Ogres, Trolls, yeeks, and & demons -DGK
* But not skeletons, because that would include druj, making Cantoras
* amazingly tough -CFT
*/
if (c_list[z].cdefense & UNIQUE) {
j = c_list[z].cchar;
if ((j=='k')||(j=='L')||(j=='o')||(j=='O')||(j=='T')||(j=='y')||
(j=='I')||(j=='&')) {
for (cur_pos=MAX_CREATURES-1;cur_pos>=0;cur_pos--)
if ((c_list[cur_pos].cchar==j) &&
(c_list[cur_pos].level<=c_list[z].level) &&
!(c_list[cur_pos].cdefense & UNIQUE)) {
count = 0;
do {
ny=y+randint(7)-4;
nx=x+randint(7)-4;
count++;
} while (!test_place(ny,nx) && (count<51));
if ((j=='k')||(j=='y')||(j=='&')||(c_list[cur_pos].cdefense&GROUP))
place_group(ny,nx,cur_pos,slp);
else
place_monster(ny,nx,cur_pos,slp);
}
}
}
return TRUE;
}
/* Places a monster at given location -RAK- */
int
place_win_monster()
{
register int y, x, cur_pos;
register monster_type *mon_ptr;
if (!total_winner) {
cur_pos = popm();
/* paranoia error check, from um55 -CFT */
if (cur_pos == -1)
return FALSE;
if (wizard || peek)
msg_print("Placing win monster");
mon_ptr = &m_list[cur_pos];
do {
y = randint(cur_height - 2);
x = randint(cur_width - 2);
}
while ((cave[y][x].fval >= MIN_CLOSED_SPACE) || (cave[y][x].cptr != 0)
|| (cave[y][x].tptr != 0) ||
(distance(y, x, char_row, char_col) <= MAX_SIGHT));
mon_ptr->fy = y;
mon_ptr->fx = x;
mon_ptr->mptr = MAX_CREATURES - 2;
if (c_list[mon_ptr->mptr].cdefense & MAX_HP)
mon_ptr->hp = max_hp(c_list[mon_ptr->mptr].hd);
else
mon_ptr->hp = pdamroll(c_list[mon_ptr->mptr].hd);
mon_ptr->cspeed = c_list[mon_ptr->mptr].speed - 10;
mon_ptr->stunned = 0;
mon_ptr->cdis = distance(char_row, char_col, y, x);
cave[y][x].cptr = cur_pos;
mon_ptr->csleep = 0;
}
return TRUE;
}
static char *
cap(str)
char *str;
{
if ((*str >= 'a') && (*str <= 'z'))
*str = *str - 'a' + 'A';
return str;
}
void
set_ghost(g, name, r, c, l)
creature_type *g;
char *name;
int r, c, l;
{
char ghost_race[20];
char ghost_class[20];
int i;
/* Allocate storage for name -TL -- braindamaged ghost name spoo -CWS */
if (c_list[MAX_CREATURES - 1].name == NULL) {
c_list[MAX_CREATURES - 1].name = (char*)malloc(101);
bzero((char *) c_list[MAX_CREATURES - 1].name, 101);
*((char *) c_list[MAX_CREATURES - 1].name) = 'A';
}
switch (r) {
case 0:
case 8:
strcpy(ghost_race, "human");
break;
case 1:
case 2:
case 9:
strcpy(ghost_race, "elf");
break;
case 3:
strcpy(ghost_race, "hobbit");
break;
case 4:
strcpy(ghost_race, "gnome");
break;
case 5:
strcpy(ghost_race, "dwarf");
break;
case 6:
strcpy(ghost_race, "orc");
break;
case 7:
strcpy(ghost_race, "troll");
break;
}
switch (c) {
case 0:
strcpy(ghost_class, "warrior");
break;
case 1:
strcpy(ghost_class, "mage");
break;
case 2:
strcpy(ghost_class, "priest");
break;
case 3:
strcpy(ghost_class, "rogue");
break;
case 4:
strcpy(ghost_class, "ranger");
break;
case 5:
strcpy(ghost_class, "paladin");
break;
}
g->level = l;
g->sleep = 0;
g->aaf = 100;
g->mexp = l * 5 + 5;
g->spells2 = NONE8;
if (!dun_level) {
sprintf((char *)g->name, "%s, the %s %s", cap(name),
cap(ghost_race), cap(ghost_class));
g->cmove |= (THRO_DR | MV_ATT_NORM | CARRY_OBJ | HAS_90 | HAS_60 | GOOD);
if (l > 10)
g->cmove |= (HAS_1D2);
if (l > 18)
g->cmove |= (HAS_2D2);
if (l > 23)
g->cmove |= (HAS_4D2);
if (l > 40) {
g->cmove |= (SPECIAL);
g->cmove &= (~HAS_4D2);
}
for (i = 0; i <= (l / 5); i++) /* Add some random resists -DGK */
switch ((int) randint(13)) {
case 1:
case 2:
case 3:
g->cdefense |= (IM_FIRE);
case 4:
case 5:
case 6:
g->cdefense |= (IM_ACID);
case 7:
case 8:
case 9:
g->cdefense |= (IM_FROST);
case 10:
case 11:
case 12:
g->cdefense |= (IM_LIGHTNING);
case 13:
g->cdefense |= (IM_POISON);
}
switch (c) {
case 0: /* Warrior */
g->spells = NONE8;
break;
case 1: /* Mage */
g->spells |= (0x3L | BLINK | MAG_MISS | SLOW | CONFUSION);
if (l > 5)
g->spells2 |= ST_CLOUD;
if (l > 7)
g->spells2 |= LIGHT_BOLT;
if (l > 10)
g->spells |= FROST_BOLT;
if (l > 12)
g->spells |= TELE;
if (l > 15)
g->spells |= ACID_BOLT;
if (l > 20)
g->spells |= FIRE_BOLT;
if (l > 25)
g->spells |= FROST_BALL;
if (l > 25)
g->spells2 |= HASTE;
if (l > 30)
g->spells |= FIRE_BALL;
if (l > 40)
g->spells |= MANA_BOLT;
break;
case 3: /* Rogue */
g->spells |= (0x5L | BLINK);
if (l > 10)
g->spells |= CONFUSION;
if (l > 18)
g->spells |= SLOW;
if (l > 25)
g->spells |= TELE;
if (l > 30)
g->spells |= HOLD_PERSON;
if (l > 35)
g->spells |= TELE_TO;
break;
case 4: /* Ranger */
g->spells |= (0x8L | MAG_MISS);
if (l > 5)
g->spells2 |= ST_CLOUD;
if (l > 7)
g->spells2 |= LIGHT_BOLT;
if (l > 10)
g->spells |= FROST_BOLT;
if (l > 18)
g->spells |= ACID_BOLT;
if (l > 25)
g->spells |= FIRE_BOLT;
if (l > 30)
g->spells |= FROST_BALL;
if (l > 35)
g->spells |= FIRE_BALL;
break;
case 2: /* Priest */
case 5: /* Paladin */
g->spells |= (0x4L | CAUSE_LIGHT | FEAR);
if (l > 5)
g->spells2 |= HEAL;
if (l > 10)
g->spells |= (CAUSE_SERIOUS | BLINDNESS);
if (l > 18)
g->spells |= HOLD_PERSON;
if (l > 25)
g->spells |= CONFUSION;
if (l > 30)
g->spells |= CAUSE_CRIT;
if (l > 35)
g->spells |= MANA_DRAIN;
break;
}
g->cdefense |= (CHARM_SLEEP | EVIL);
if (r == 6)
g->cdefense |= ORC;
else if (r == 7)
g->cdefense |= TROLL;
g->ac = 15 + randint(15);
if (c == 0 || c >= 3)
g->ac += randint(60);
if ((c == 1 || c == 3) && l > 25) /* High level mages and
* rogues are fast... */
g->speed = 12;
else
g->speed = 11;
g->cchar = 'p';
g->hd[1] = 1;
g->damage[0] = 5 + ((l > 18) ? 18 : l);
g->damage[1] = g->damage[0];
switch (c) {
case 0:
g->damage[2] = ((l < 30) ? (5 + ((l > 18) ? 18 : l)) : 235);
g->damage[3] = g->damage[2];
break;
case 1:
case 2:
g->damage[2] = 0;
g->damage[3] = 0;
break;
case 3:
g->damage[2] = g->damage[3] = ((l < 30) ? 149 : 232);
break;
case 5:
case 4:
g->damage[2] = g->damage[3] = g->damage[1];
break;
}
return;
}
switch ((int) (g->level / 4) + randint(3)) {
case 1:
case 2:
case 3:
sprintf((char *)g->name, "%s, the Skeleton %s", name, ghost_race);
g->cmove |= (THRO_DR | MV_ATT_NORM | CARRY_OBJ | HAS_90 | GOOD);
g->spells |= (NONE8);
g->cdefense |= (IM_POISON | CHARM_SLEEP | UNDEAD | EVIL | IM_FROST | NO_INFRA);
if (r == 6)
g->cdefense |= ORC;
else if (r == 7)
g->cdefense |= TROLL;
g->ac = 26;
g->speed = 11;
g->cchar = 's';
g->hd[1] = 1;
g->damage[0] = 5;
g->damage[1] = 5;
g->damage[2] = 0;
g->damage[3] = 0;
break;
case 4:
case 5:
sprintf((char *)g->name, "%s, the %s zombie", name, cap(ghost_race));
g->cmove |= (THRO_DR | MV_ATT_NORM | CARRY_OBJ | HAS_60 | HAS_90 | GOOD);
g->spells |= (NONE8);
g->cdefense |= (IM_POISON | CHARM_SLEEP | UNDEAD | EVIL | NO_INFRA);
if (r == 6)
g->cdefense |= ORC;
else if (r == 7)
g->cdefense |= TROLL;
g->ac = 30;
g->speed = 11;
g->cchar = 'z';
g->hd[1] *= 2;
g->damage[0] = 8;
g->damage[1] = 0;
g->damage[2] = 0;
g->damage[3] = 0;
break;
case 6:
sprintf((char *) g->name, "%s, the Poltergeist", name);
g->cmove |= (MV_INVIS | MV_ATT_NORM | CARRY_OBJ |
GOOD | HAS_1D2 | MV_75 | THRO_WALL);
g->spells |= (NONE8);
g->cdefense |= (IM_POISON | CHARM_SLEEP | UNDEAD | EVIL | IM_FROST | NO_INFRA);
g->ac = 20;
g->speed = 13;
g->cchar = 'G';
g->damage[0] = 5;
g->damage[1] = 5;
g->damage[2] = 93;
g->damage[3] = 93;
g->mexp = (g->mexp * 3) / 2;
break;
case 7:
case 8:
sprintf((char *)g->name, "%s, the Mummified %s", name, cap(ghost_race));
g->cmove |= (MV_ATT_NORM | CARRY_OBJ | HAS_1D2 | GOOD);
g->spells |= (NONE8);
g->cdefense |= (CHARM_SLEEP | UNDEAD | EVIL | IM_POISON | NO_INFRA);
if (r == 6)
g->cdefense |= ORC;
else if (r == 7)
g->cdefense |= TROLL;
g->ac = 35;
g->speed = 11;
g->cchar = 'M';
g->hd[1] *= 2;
g->damage[0] = 16;
g->damage[1] = 16;
g->damage[2] = 16;
g->damage[3] = 0;
g->mexp = (g->mexp * 3) / 2;
break;
case 9:
case 10:
sprintf((char *)g->name, "%s%s spirit", name, (name[strlen(name) - 1] == 's') ?
"'" : "'s");
g->cmove |= (MV_INVIS | THRO_WALL | MV_ATT_NORM | CARRY_OBJ | HAS_1D2 | GOOD);
g->spells |= (NONE8);
g->cdefense |= (CHARM_SLEEP | UNDEAD | EVIL | IM_POISON | IM_FROST | NO_INFRA);
g->ac = 20;
g->speed = 11;
g->cchar = 'G';
g->hd[1] *= 2;
g->damage[0] = 19;
g->damage[1] = 185;
g->damage[2] = 99;
g->damage[3] = 178;
g->mexp = g->mexp * 3;
break;
case 11:
sprintf((char *)g->name, "%s%s ghost", name, (name[strlen(name) - 1] == 's') ?
"'" : "'s");
g->cmove |= (MV_INVIS | THRO_WALL | MV_ATT_NORM | CARRY_OBJ | HAS_1D2 | GOOD);
g->spells |= (0xFL | HOLD_PERSON | MANA_DRAIN | BLINDNESS);
g->cdefense |= (CHARM_SLEEP | UNDEAD | EVIL | IM_POISON | IM_FROST | NO_INFRA);
g->ac = 40;
g->speed = 12;
g->cchar = 'G';
g->hd[1] *= 2;
g->damage[0] = 99;
g->damage[1] = 99;
g->damage[2] = 192;
g->damage[3] = 184;
g->mexp = (g->mexp * 7) / 2;
break;
case 12:
sprintf((char *) g->name, "%s, the Vampire", name);
g->cmove |= (THRO_DR | MV_ATT_NORM | CARRY_OBJ | HAS_2D2 | GOOD);
g->spells |= (0x8L | HOLD_PERSON | FEAR | TELE_TO | CAUSE_SERIOUS);
g->cdefense |= (CHARM_SLEEP | UNDEAD | EVIL | IM_POISON | NO_INFRA | HURT_LIGHT);
g->ac = 40;
g->speed = 11;
g->cchar = 'V';
g->hd[1] *= 3;
g->damage[0] = 20;
g->damage[1] = 20;
g->damage[2] = 190;
g->damage[3] = 0;
g->mexp = g->mexp * 3;
break;
case 13:
sprintf((char *)g->name, "%s%s Wraith", name, (name[strlen(name) - 1] == 's') ?
"'" : "'s");
g->cmove |= (THRO_DR | MV_ATT_NORM | CARRY_OBJ | HAS_4D2 | HAS_2D2 | GOOD);
g->spells |= (0x7L | HOLD_PERSON | FEAR | BLINDNESS | CAUSE_CRIT);
g->spells2 |= (NETHER_BOLT);
g->cdefense |= (CHARM_SLEEP | UNDEAD | EVIL | IM_POISON | IM_FROST | NO_INFRA |
HURT_LIGHT);
g->ac = 60;
g->speed = 12;
g->cchar = 'W';
g->hd[1] *= 3;
g->damage[0] = 20;
g->damage[1] = 20;
g->damage[2] = 190;
g->damage[3] = 0;
g->mexp = g->mexp * 5;
break;
case 14:
sprintf((char *) g->name, "%s, the Vampire Lord", name);
g->cmove |= (THRO_DR | MV_ATT_NORM | CARRY_OBJ | HAS_1D2 | SPECIAL);
g->spells |= (0x8L | HOLD_PERSON | FEAR | TELE_TO | CAUSE_CRIT);
g->spells2 |= (NETHER_BOLT);
g->cdefense |= (CHARM_SLEEP | UNDEAD | EVIL | IM_POISON | NO_INFRA | HURT_LIGHT);
g->ac = 80;
g->speed = 11;
g->cchar = 'V';
g->hd[1] *= 2;
g->hd[0] = (g->hd[0] * 5) / 2;
g->damage[0] = 20;
g->damage[1] = 20;
g->damage[2] = 20;
g->damage[3] = 198;
g->mexp = g->mexp * 20;
break;
case 15:
sprintf((char *)g->name, "%s%s ghost", name, (name[strlen(name) - 1] == 's') ?
"'" : "'s");
g->cmove |= (MV_INVIS | THRO_WALL | MV_ATT_NORM | CARRY_OBJ | HAS_2D2 | SPECIAL);
g->spells |= (0x5L | HOLD_PERSON | MANA_DRAIN | BLINDNESS | CONFUSION);
g->cdefense |= (CHARM_SLEEP | UNDEAD | EVIL | IM_FROST | IM_POISON | NO_INFRA);
g->ac = 90;
g->speed = 13;
g->cchar = 'G';
g->hd[1] *= 3;
g->damage[0] = 99;
g->damage[1] = 99;
g->damage[2] = 192;
g->damage[3] = 184;
g->mexp = g->mexp * 20;
break;
case 17:
sprintf((char *)g->name, "%s, the Lich", name);
g->cmove |= (THRO_DR | MV_ATT_NORM | CARRY_OBJ | HAS_2D2 | HAS_1D2 | SPECIAL);
g->spells |= (0x3L | FEAR | CAUSE_CRIT | TELE_TO | BLINK | S_UNDEAD | FIRE_BALL |
FROST_BALL | HOLD_PERSON | MANA_DRAIN | BLINDNESS | CONFUSION | TELE);
g->spells2 |= (BRAIN_SMASH | RAZOR);
g->cdefense |= (CHARM_SLEEP | UNDEAD | EVIL | IM_FROST | NO_INFRA | IM_POISON
| INTELLIGENT);
g->ac = 120;
g->speed = 12;
g->cchar = 'L';
g->hd[1] *= 3;
g->hd[0] *= 2;
g->damage[0] = 181;
g->damage[1] = 201;
g->damage[2] = 214;
g->damage[3] = 181;
g->mexp = g->mexp * 50;
break;
case 18:
default:
sprintf((char *)g->name, "%s%s ghost", name, (name[strlen(name) - 1] == 's') ?
"'" : "'s");
g->cmove |= (MV_INVIS | THRO_WALL | MV_ATT_NORM | CARRY_OBJ |
HAS_1D2 | HAS_2D2 | SPECIAL);
g->spells |= (0x2L | HOLD_PERSON | MANA_DRAIN | BLINDNESS | CONFUSION | TELE_TO);
g->spells2 |= (NETHER_BOLT | NETHER_BALL | BRAIN_SMASH | TELE_LEV);
g->cdefense |= (CHARM_SLEEP | UNDEAD | EVIL | IM_POISON | IM_FROST | NO_INFRA |
INTELLIGENT);
g->ac = 130;
g->speed = 13;
g->cchar = 'G';
g->hd[1] *= 2;
g->hd[0] = (g->hd[0] * 5) / 2;
g->damage[0] = 99;
g->damage[1] = 99;
g->damage[2] = 192;
g->damage[3] = 184;
g->mexp = g->mexp * 30;
break;
}
}
/* Places a monster at given location -RAK- */
int
place_ghost()
{
register int y, x, cur_pos;
register monster_type *mon_ptr;
creature_type *ghost = &c_list[MAX_CREATURES - 1];
char tmp[100];
char name[100];
int i, j, level;
int ghost_race;
int cl;
if (!dun_level) {
FILE *fp;
if (py.misc.lev < 5 || randint(10) > 1)
return 0;
sprintf(tmp, "%s/%d", ANGBAND_BONES, py.misc.lev);
if ((fp = my_tfopen(tmp, "r")) != NULL) {
if (fscanf(fp, "%[^\n]\n%d\n%d\n%d", name, &i, &ghost_race, &cl) < 4) {
fclose(fp);
if (wizard)
msg_print("Town:Failed to scan in info properly!");
return 0;
}
fclose(fp);
j = 1;
if (i > 255) { /* avoid wrap-around of int8u hitdice, by
* factoring */
j = i / 32;
i = 32;
}
ghost->hd[0] = i; /* set_ghost may adj for race/class/lv */
ghost->hd[1] = j;
level = py.misc.lev;
} else {
return 0;
}
} else {
if (14 > randint((dun_level / 2) + 11))
return 0;
if (randint(3) == 1) {
FILE *fp;
sprintf(tmp, "%s/%d", ANGBAND_BONES, dun_level);
if ((fp = my_tfopen(tmp, "r")) != NULL) {
if (fscanf(fp, "%[^\n]\n%d\n%d\n%d", name, &i, &ghost_race, &cl) < 4) {
fclose(fp);
if (wizard)
msg_print("Ghost:Failed to scan in info properly!");
return 0;
}
fclose(fp);
j = 1;
if (i > 255) { /* avoid wrap-around of int8u hitdice, by
* factoring */
j = i / 32;
i = 32;
}
ghost->hd[0] = i; /* set_ghost may adj for race/class/lv */
ghost->hd[1] = j;
level = dun_level;
} else {
return 0;
}
} else {
return 0;
}
}
set_ghost(ghost, name, ghost_race, cl, level);
if (wizard || peek)
msg_print(ghost->name);
cur_pos = popm();
mon_ptr = &m_list[cur_pos];
do {
y = randint(cur_height - 2);
x = randint(cur_width - 2);
} while ((cave[y][x].fval >= MIN_CLOSED_SPACE) || (cave[y][x].cptr != 0)
|| (cave[y][x].tptr != 0) ||
(distance(y, x, char_row, char_col) <= MAX_SIGHT));
mon_ptr->fy = y;
mon_ptr->fx = x;
mon_ptr->mptr = (MAX_CREATURES - 1);
mon_ptr->hp = (int16) ghost->hd[0] * (int16) ghost->hd[1];
/* the c_list speed value is 10 greater, so that it can be a int8u */
mon_ptr->cspeed = c_list[mon_ptr->mptr].speed - 10;
mon_ptr->stunned = 0;
mon_ptr->cdis = distance(char_row, char_col, y, x);
cave[y][x].cptr = cur_pos;
mon_ptr->csleep = 0;
return 1;
}
/*
* Return a monster suitable to be placed at a given level. This makes high
* level monsters (up to the given level) slightly more common than low level
* monsters at any given level. -CJS-
*/
int
get_mons_num(level)
int level;
{
register int i, j, num;
int old = level;
again:
if (level == 0)
i = randint(m_level[0]) - 1;
else {
if (level > MAX_MONS_LEVEL)
level = MAX_MONS_LEVEL;
if (randint(MON_NASTY) == 1) {
i = level / 4 + 1; /* be a little more civilized about monster depths */
if (i > 4) /* for the first levels -CWS */
i = 4;
level = level + MY_ABS(i) + 1;
if (level > MAX_MONS_LEVEL)
level = MAX_MONS_LEVEL;
} else {
/* This code has been added to make it slightly more likely to get
* the higher level monsters. Originally a uniform distribution over
* all monsters of level less than or equal to the dungeon level.
* This distribution makes a level n monster occur approx 2/n% of the
* time on level n, and 1/n*n% are 1st level.
*/
num = m_level[level] - m_level[0];
i = randint(num) - 1;
j = randint(num) - 1;
if (j > i)
i = j;
level = c_list[i + m_level[0]].level;
}
i = m_level[level] - m_level[level - 1];
if (i == 0)
i++;
i = randint(i) - 1 + m_level[level - 1];
}
if ((c_list[i].level > old) && (c_list[i].cdefense & UNIQUE))
goto again;
if ((c_list[i].level > (unsigned) dun_level) &&
(c_list[i].cdefense & QUESTOR))
goto again;
return i;
}
int
get_nmons_num(level)
int level;
{
register int i, j, num;
int old;
old = level;
again:
if (level == 0)
i = randint(m_level[0]) - 1;
else {
if (level > MAX_MONS_LEVEL)
level = MAX_MONS_LEVEL;
num = m_level[level] - m_level[0];
i = randint(num) - 1;
i += 15;
if (i >= num)
i = num - 1;
j = randint(num) - 1;
if (j > i)
i = j;
j = randint(num) - 1;
if (j > i)
i = j;
level = c_list[i + m_level[0]].level;
i = m_level[level] - m_level[level - 1];
if (i == 0)
i = 1;
i = randint(i) - 1 + m_level[level - 1];
}
if ((c_list[i].level > old) && (c_list[i].cdefense & UNIQUE))
goto again;
if (( c_list[i].level > (unsigned) dun_level) &&
(c_list[i].cdefense & QUESTOR))
goto again;
return i;
}
/* Ludwig's Brainstorm */
static int
test_place(y, x)
int y, x;
{
if (!in_bounds(y, x) ||
(cave[y][x].fval >= MIN_CLOSED_SPACE) ||
(cave[y][x].fval == NULL_WALL) ||
(cave[y][x].cptr != 0) ||
(y == char_row && x == char_col))
return (0);
return (1);
}
void
place_group(y, x, mon, slp)
int y, x, mon, slp;
{
/* prevent level rating from skyrocketing if they are out of depth... */
int old = rating;
int extra = 0;
if (c_list[mon].level > (unsigned) dun_level)
extra = (-randint(c_list[mon].level - dun_level));
/* reduce size of group if out-of-depth */
else if (c_list[mon].level < (unsigned) dun_level)
/* if monster is deeper than normal, then travel in bigger packs -CFT */
extra = randint(dun_level - c_list[mon].level);
if (extra > 12)
extra = 12; /* put an upper bounds on it... -CFT */
switch (randint(13) + extra) {
case 25:
place_monster(y, x - 3, mon, 0);
case 24:
place_monster(y, x + 3, mon, 0);
case 23:
place_monster(y - 3, x, mon, 0);
case 22:
place_monster(y + 3, x, mon, 0);
case 21:
place_monster(y - 2, x + 1, mon, 0);
case 20:
place_monster(y + 2, x - 1, mon, 0);
case 19:
place_monster(y + 2, x + 1, mon, 0);
case 18:
place_monster(y - 2, x - 1, mon, 0);
case 17:
place_monster(y + 1, x + 2, mon, 0);
case 16:
place_monster(y - 1, x - 2, mon, 0);
case 15:
place_monster(y + 1, x - 2, mon, 0);
case 14:
place_monster(y - 1, x + 2, mon, 0);
case 13:
place_monster(y, x - 2, mon, 0);
case 12:
place_monster(y, x + 2, mon, 0);
case 11:
place_monster(y + 2, x, mon, 0);
case 10:
place_monster(y - 2, x, mon, 0);
case 9:
place_monster(y + 1, x + 1, mon, 0);
case 8:
place_monster(y + 1, x - 1, mon, 0);
case 7:
place_monster(y - 1, x - 1, mon, 0);
case 6:
place_monster(y - 1, x + 1, mon, 0);
case 5:
place_monster(y, x + 1, mon, 0);
case 4:
place_monster(y, x - 1, mon, 0);
case 3:
place_monster(y + 1, x, mon, 0);
case 2:
place_monster(y - 1, x, mon, 0);
rating = old;
case 1:
default: /* just in case I screwed up -CFT */
place_monster(y, x, mon, 0);
}
}
/* Allocates a random monster -RAK- */
void
alloc_monster(num, dis, slp)
int num, dis, slp;
{
register int y, x, i;
int mon;
for (i = 0; i < num; i++) {
do {
y = randint(cur_height - 2);
x = randint(cur_width - 2);
}
while (cave[y][x].fval >= MIN_CLOSED_SPACE || (cave[y][x].cptr != 0) ||
(distance(y, x, char_row, char_col) <= dis));
do {
mon = get_mons_num(dun_level);
} while (randint(c_list[mon].rarity) > 1);
/*
* to give the player a sporting chance, any monster that appears in
* line-of-sight and can cast spells or breathe, should be asleep. This
* is an extension of Um55's sleeping dragon code...
*/
if (((c_list[mon].spells & (CAUSE_LIGHT | CAUSE_SERIOUS | HOLD_PERSON |
BLINDNESS | CONFUSION | FEAR | SLOW | BREATH_L |
BREATH_G | BREATH_A | BREATH_FR | BREATH_FI |
FIRE_BOLT | FROST_BOLT | ACID_BOLT | MAG_MISS |
CAUSE_CRIT | FIRE_BALL | FROST_BALL | MANA_BOLT))
|| (c_list[mon].spells2 & (BREATH_CH | BREATH_SH | BREATH_SD | BREATH_CO |
BREATH_DI | BREATH_LD | LIGHT_BOLT | LIGHT_BALL |
ACID_BALL | TRAP_CREATE | RAZOR | MIND_BLAST |
MISSILE | PLASMA_BOLT | NETHER_BOLT | ICE_BOLT |
FORGET | BRAIN_SMASH | ST_CLOUD | TELE_LEV |
WATER_BOLT | WATER_BALL | NETHER_BALL | BREATH_NE))
|| (c_list[mon].spells3 & (BREATH_WA | BREATH_SL | BREATH_LT | BREATH_TI |
BREATH_GR | BREATH_DA | BREATH_PL | ARROW |
DARK_STORM | MANA_STORM)))
&& (los(y, x, char_row, char_col)))
slp = TRUE;
if (!(c_list[mon].cdefense & GROUP))
place_monster(y, x, mon, slp);
else
place_group(y, x, mon, slp);
}
}
/* Places creature adjacent to given location -RAK- */
int
summon_monster(y, x, slp)
int *y, *x;
int slp;
{
register int i, j, k;
int l, summon;
register cave_type *cave_ptr;
i = 0;
summon = FALSE;
l = get_mons_num(dun_level + MON_SUMMON_ADJ);
do {
j = *y - 2 + randint(3);
k = *x - 2 + randint(3);
if (in_bounds(j, k)) {
cave_ptr = &cave[j][k];
if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0)) {
if (c_list[l].cdefense & GROUP)
place_group(j, k, l, slp);
else
place_monster(j, k, l, slp);
summon = TRUE;
i = 9;
*y = j;
*x = k;
}
}
i++;
}
while (i <= 9);
return (summon);
}
/* Places undead adjacent to given location -RAK- */
int
summon_undead(y, x)
int *y, *x;
{
register int i, j, k;
int l, m, ctr, summon;
register cave_type *cave_ptr;
i = 0;
summon = FALSE;
l = m_level[MAX_MONS_LEVEL];
do {
m = randint(l) - 1;
ctr = 0;
do {
if ((c_list[m].cdefense & UNDEAD) && !(c_list[m].cdefense & UNIQUE) &&
(c_list[m].level < dun_level + 5)) {
ctr = 20;
l = 0;
} else {
m++;
if (m > l)
ctr = 20;
else
ctr++;
}
} while (ctr <= 19);
} while (l != 0);
do {
j = *y - 2 + randint(3);
k = *x - 2 + randint(3);
if (in_bounds(j, k)) {
cave_ptr = &cave[j][k];
if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0)) {
place_monster(j, k, m, FALSE);
summon = TRUE;
i = 9;
*y = j;
*x = k;
}
}
i++;
} while (i <= 9);
return (summon);
}
/* As for summon undead */
int
summon_demon(lev, y, x)
int lev;
int *y, *x;
{
register int i, j, k;
int l, m, ctr, summon;
register cave_type *cave_ptr;
i = 0;
summon = FALSE;
l = m_level[MAX_MONS_LEVEL];
do {
m = randint(l) - 1;
ctr = 0;
do {
if (c_list[m].cdefense & DEMON && !(c_list[m].cdefense & UNIQUE) &&
(c_list[m].level <= lev)) {
ctr = 20;
l = 0;
} else {
m++;
if (m > l)
ctr = 20;
else
ctr++;
}
} while (ctr <= 19);
} while (l != 0);
do {
j = *y - 2 + randint(3);
k = *x - 2 + randint(3);
if (in_bounds(j, k)) {
cave_ptr = &cave[j][k];
if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0)) {
place_monster(j, k, m, FALSE);
summon = TRUE;
i = 9;
*y = j;
*x = k;
}
}
i++;
} while (i <= 9);
return (summon);
}
/* As for summon demon:-) ~Ludwig */
int
summon_dragon(y, x)
int *y, *x;
{
register int i, j, k;
int l, m, ctr, summon;
register cave_type *cave_ptr;
i = 0;
summon = FALSE;
l = m_level[MAX_MONS_LEVEL];
do {
m = randint(l) - 1;
ctr = 0;
do {
if (c_list[m].cdefense & DRAGON && !(c_list[m].cdefense & UNIQUE)) {
ctr = 20;
l = 0;
} else {
m++;
if (m > l)
ctr = 20;
else
ctr++;
}
}
while (ctr <= 19);
}
while (l != 0);
do {
j = *y - 2 + randint(3);
k = *x - 2 + randint(3);
if (in_bounds(j, k)) {
cave_ptr = &cave[j][k];
if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0)) {
place_monster(j, k, m, FALSE);
summon = TRUE;
i = 9;
*y = j;
*x = k;
}
}
i++;
}
while (i <= 9);
return (summon);
}
/* Summon ringwraiths */
int
summon_wraith(y, x)
int *y, *x;
{
register int i, j, k;
int l, m, ctr, summon;
register cave_type *cave_ptr;
i = 0;
summon = FALSE;
l = m_level[MAX_MONS_LEVEL];
do {
m = randint(l) - 1;
ctr = 0;
do {
if (c_list[m].cchar == 'W' && (c_list[m].cdefense & UNIQUE)) {
ctr = 20;
l = 0;
} else {
m++;
if (m > l)
ctr = 20;
else
ctr++;
}
}
while (ctr <= 19);
}
while (l != 0);
do {
j = *y - 2 + randint(3);
k = *x - 2 + randint(3);
if (in_bounds(j, k)) {
cave_ptr = &cave[j][k];
if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0)) {
place_monster(j, k, m, FALSE);
summon = TRUE;
i = 9;
*y = j;
*x = k;
}
}
i++;
}
while (i <= 9);
return (summon);
}
/* Summon reptiles */
int
summon_reptile(y, x)
int *y, *x;
{
register int i, j, k;
int l, m, ctr, summon;
register cave_type *cave_ptr;
i = 0;
summon = FALSE;
l = m_level[MAX_MONS_LEVEL];
do {
m = randint(l) - 1;
ctr = 0;
do {
if (c_list[m].cchar == 'R' && !(c_list[m].cdefense & UNIQUE)) {
ctr = 20;
l = 0;
} else {
m++;
if (m > l)
ctr = 20;
else
ctr++;
}
}
while (ctr <= 19);
}
while (l != 0);
do {
j = *y - 2 + randint(3);
k = *x - 2 + randint(3);
if (in_bounds(j, k)) {
cave_ptr = &cave[j][k];
if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0)) {
place_monster(j, k, m, FALSE);
summon = TRUE;
i = 9;
*y = j;
*x = k;
}
}
i++;
}
while (i <= 9);
return (summon);
}
/* As for summon dragon, but keys on character ~Decado */
int
summon_spider(y, x)
int *y, *x;
{
register int i, j, k;
int l, m, ctr, summon;
register cave_type *cave_ptr;
i = 0;
summon = FALSE;
l = m_level[MAX_MONS_LEVEL];
do {
m = randint(l) - 1;
ctr = 0;
do {
if (c_list[m].cchar == 'S' && !(c_list[m].cdefense & UNIQUE)) {
ctr = 20;
l = 0;
} else {
m++;
if (m > l)
ctr = 20;
else
ctr++;
}
}
while (ctr <= 19);
}
while (l != 0);
do {
j = *y - 2 + randint(3);
k = *x - 2 + randint(3);
if (in_bounds(j, k)) {
cave_ptr = &cave[j][k];
if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0)) {
place_monster(j, k, m, FALSE);
summon = TRUE;
i = 9;
*y = j;
*x = k;
}
}
i++;
}
while (i <= 9);
return (summon);
}
/* As for summon dragon, but keys on character ~Decado */
int
summon_angel(y, x)
int *y, *x;
{
register int i, j, k;
int l, m, ctr, summon;
register cave_type *cave_ptr;
i = 0;
summon = FALSE;
l = m_level[MAX_MONS_LEVEL];
do {
m = randint(l) - 1;
ctr = 0;
do {
if (c_list[m].cchar == 'A' && !(c_list[m].cdefense & UNIQUE)) {
ctr = 20;
l = 0;
} else {
m++;
if (m > l)
ctr = 20;
else
ctr++;
}
} while (ctr <= 19);
}
while (l != 0);
do {
j = *y - 2 + randint(3);
k = *x - 2 + randint(3);
if (in_bounds(j, k)) {
cave_ptr = &cave[j][k];
if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0)) {
place_monster(j, k, m, FALSE);
summon = TRUE;
i = 9;
*y = j;
*x = k;
}
}
i++;
} while (i <= 9);
return (summon);
}
/* Summon ants */
int
summon_ant(y, x)
int *y, *x;
{
register int i, j, k;
int l, m, ctr, summon;
register cave_type *cave_ptr;
i = 0;
summon = FALSE;
l = m_level[MAX_MONS_LEVEL];
do {
m = randint(l) - 1;
ctr = 0;
do {
if (c_list[m].cchar == 'a' && !(c_list[m].cdefense & UNIQUE)) {
ctr = 20;
l = 0;
} else {
m++;
if (m > l)
ctr = 20;
else
ctr++;
}
}
while (ctr <= 19);
}
while (l != 0);
do {
j = *y - 2 + randint(3);
k = *x - 2 + randint(3);
if (in_bounds(j, k)) {
cave_ptr = &cave[j][k];
if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0)) {
place_monster(j, k, m, FALSE);
summon = TRUE;
i = 9;
*y = j;
*x = k;
}
}
i++;
}
while (i <= 9);
return (summon);
}
/* Summon uniques */
int
summon_unique(y, x)
int *y, *x;
{
register int i, j, k;
int l, m, ctr, summon;
register cave_type *cave_ptr;
i = 0;
summon = FALSE;
l = m_level[MAX_MONS_LEVEL];
do {
m = randint(l) - 1;
ctr = 0;
do {
if (!(c_list[m].cchar == 'P') && (c_list[m].cdefense & UNIQUE)) {
ctr = 20;
l = 0;
} else {
m++;
if (m > l)
ctr = 20;
else
ctr++;
}
}
while (ctr <= 19);
}
while (l != 0);
do {
j = *y - 2 + randint(3);
k = *x - 2 + randint(3);
if (in_bounds(j, k)) {
cave_ptr = &cave[j][k];
if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0)) {
place_monster(j, k, m, FALSE);
summon = TRUE;
i = 9;
*y = j;
*x = k;
}
}
i++;
}
while (i <= 9);
return (summon);
}
/* Summon jabberwocks, for extra effect to the summon_unique spell */
int
summon_jabberwock(y, x)
int *y, *x;
{
register int i, j, k;
int l, m, ctr, summon;
register cave_type *cave_ptr;
i = 0;
summon = FALSE;
l = m_level[MAX_MONS_LEVEL];
do {
m = randint(l) - 1;
ctr = 0;
do {
if (c_list[m].cchar == 'J' && !(c_list[m].cdefense & UNIQUE)) {
ctr = 20;
l = 0;
} else {
m++;
if (m > l)
ctr = 20;
else
ctr++;
}
}
while (ctr <= 19);
}
while (l != 0);
do {
j = *y - 2 + randint(3);
k = *x - 2 + randint(3);
if (in_bounds(j, k)) {
cave_ptr = &cave[j][k];
if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0)) {
place_monster(j, k, m, FALSE);
summon = TRUE;
i = 9;
*y = j;
*x = k;
}
}
i++;
}
while (i <= 9);
return (summon);
}
/* Summon greater undead */
int
summon_gundead(y, x)
int *y, *x;
{
register int i, j, k;
int l, m, ctr, summon;
register cave_type *cave_ptr;
i = 0;
summon = FALSE;
l = m_level[MAX_MONS_LEVEL];
do {
m = randint(l) - 1;
ctr = 0;
do {
if ((c_list[m].cchar == 'L') || (c_list[m].cchar == 'V')
|| (c_list[m].cchar == 'W')) {
ctr = 20;
l = 0;
} else {
m++;
if (m > l)
ctr = 20;
else
ctr++;
}
}
while (ctr <= 19);
}
while (l != 0);
do {
j = *y - 2 + randint(3);
k = *x - 2 + randint(3);
if (in_bounds(j, k)) {
cave_ptr = &cave[j][k];
if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0)) {
place_monster(j, k, m, FALSE);
summon = TRUE;
i = 9;
*y = j;
*x = k;
}
}
i++;
}
while (i <= 9);
return (summon);
}
/* Summon ancient dragons */
int
summon_ancientd(y, x)
int *y, *x;
{
register int i, j, k;
int l, m, ctr, summon;
register cave_type *cave_ptr;
i = 0;
summon = FALSE;
l = m_level[MAX_MONS_LEVEL];
do {
m = randint(l) - 1;
ctr = 0;
do {
if (c_list[m].cchar == 'D') {
ctr = 20;
l = 0;
} else {
m++;
if (m > l)
ctr = 20;
else
ctr++;
}
}
while (ctr <= 19);
}
while (l != 0);
do {
j = *y - 2 + randint(3);
k = *x - 2 + randint(3);
if (in_bounds(j, k)) {
cave_ptr = &cave[j][k];
if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0)) {
place_monster(j, k, m, FALSE);
summon = TRUE;
i = 9;
*y = j;
*x = k;
}
}
i++;
}
while (i <= 9);
return (summon);
}
/* As for summon hound, but keys on character ~Decado */
int
summon_hound(y, x)
int *y, *x;
{
register int i, j, k;
int l, m, ctr, summon;
register cave_type *cave_ptr;
i = 0;
summon = FALSE;
l = m_level[MAX_MONS_LEVEL];
do {
m = randint(l) - 1;
ctr = 0;
do {
if ((c_list[m].cchar == 'C' || c_list[m].cchar == 'Z')
&& !(c_list[m].cdefense & UNIQUE)) {
ctr = 20;
l = 0;
} else {
m++;
if (m > l)
ctr = 20;
else
ctr++;
}
}
while (ctr <= 19);
}
while (l != 0);
do {
j = *y - 2 + randint(3);
k = *x - 2 + randint(3);
if (in_bounds(j, k)) {
cave_ptr = &cave[j][k];
if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0)) {
place_monster(j, k, m, FALSE);
summon = TRUE;
i = 9;
*y = j;
*x = k;
}
}
i++;
}
while (i <= 9);
return (summon);
}
/* Place a sleepy jelly at the required coordinates ~Ludwig */
int
summon_jelly(y, x)
int *y, *x;
{
int l, m, summon;
summon = FALSE;
l = m_level[MAX_MONS_LEVEL];
do {
m = randint(l) - 1;
if (c_list[m].cchar == 'J') {
summon = TRUE;
place_monster(*y, *x, m, TRUE);
}
} while (!summon);
return (summon);
}
/* If too many objects on floor level, delete some of them */
static void
compact_objects()
{
register int i, j;
int ctr, cur_dis, chance;
register cave_type *cave_ptr;
msg_print("Compacting objects...");
ctr = 0;
cur_dis = 66;
do {
for (i = 0; i < cur_height; i++)
for (j = 0; j < cur_width; j++) {
cave_ptr = &cave[i][j];
if ((cave_ptr->tptr != 0)
&& (distance(i, j, char_row, char_col) > cur_dis)) {
switch (t_list[cave_ptr->tptr].tval) {
case TV_VIS_TRAP:
chance = 15;
break;
case TV_INVIS_TRAP:
case TV_RUBBLE:
case TV_OPEN_DOOR:
case TV_CLOSED_DOOR:
chance = 5;
break;
case TV_UP_STAIR:
case TV_DOWN_STAIR:
case TV_STORE_DOOR:
chance = 0;
break;
case TV_SECRET_DOOR: /* secret doors */
chance = 3;
break;
default:
if ((t_list[cave_ptr->tptr].tval >= TV_MIN_WEAR) &&
(t_list[cave_ptr->tptr].tval <= TV_MAX_WEAR) &&
(t_list[cave_ptr->tptr].flags2 & TR_ARTIFACT))
chance = 0; /* don't compact artifacts -CFT */
else
chance = 10;
}
if (randint(100) <= chance) {
(void)delete_object(i, j);
ctr++;
}
}
}
if (ctr == 0)
cur_dis -= 6;
}
while (ctr <= 0);
if (cur_dis < 66)
prt_map();
}
/* Gives pointer to next free space -RAK- */
int
popt()
{
if (tcptr == MAX_TALLOC)
compact_objects();
return (tcptr++);
}
/* Pushs a record back onto free space list -RAK- */
/*
* Delete_object() should always be called instead, unless the object in
* question is not in the dungeon, e.g. in store1.c and files.c
*/
void
pusht(my_x)
int my_x;
{
int16 x = (int16) my_x;
register int i, j;
if (x != tcptr - 1) {
t_list[x] = t_list[tcptr - 1];
/* must change the tptr in the cave of the object just moved */
for (i = 0; i < cur_height; i++)
for (j = 0; j < cur_width; j++)
if (cave[i][j].tptr == tcptr - 1)
cave[i][j].tptr = x;
}
tcptr--;
invcopy(&t_list[tcptr], OBJ_NOTHING);
}
/* Boolean : is object enchanted -RAK- */
int
magik(chance)
int chance;
{
if (randint(100) <= chance)
return (TRUE);
else
return (FALSE);
}
/* Enchant a bonus based on degree desired -RAK- */
/*
* Lets just change this to make sense. Now it goes from base to limit,
* roughly proportional to the level.... -CWS
*/
int
m_bonus(base, limit, level)
int base, limit, level;
{
register int x, stand_dev, tmp, diff = limit - base;
/* standard deviation twice as wide at bottom of Angband as top */
stand_dev = (OBJ_STD_ADJ * (1 + level / 100)) + OBJ_STD_MIN;
/* check for level > max_std to check for overflow... */
if (stand_dev > 40)
stand_dev = 40;
/* abs may be a macro, don't call it with randnor as a parameter */
tmp = randnor(0, stand_dev);
x = (tmp * diff / 150) + (level * limit / 200) + base;
if (x < base)
return (base);
else
return (x);
}
int
unique_weapon(t_ptr)
inven_type *t_ptr;
{
const char *name;
if (be_nasty)
return 0;
name = object_list[t_ptr->index].name;
if (!stricmp("& Longsword", name)) {
switch (randint(15)) {
case 1:
if (RINGIL)
return 0;
if (wizard || peek)
msg_print("Ringil");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_RINGIL;
t_ptr->tohit = 22;
t_ptr->todam = 25;
t_ptr->damage[0] = 4;
t_ptr->flags = (TR_SEE_INVIS | TR_SLAY_UNDEAD | TR_SLAY_EVIL | TR_REGEN |
TR_SPEED | TR_RES_COLD | TR_FROST_BRAND | TR_FREE_ACT |
TR_SLOW_DIGEST);
t_ptr->flags2 |= (TR_SLAY_DEMON | TR_SLAY_TROLL | TR_LIGHT | TR_ACTIVATE
| TR_RES_LT | TR_ARTIFACT);
t_ptr->p1 = 1;
t_ptr->cost = 300000L;
RINGIL = 1;
return 1;
case 2:
case 3:
case 4:
if (ANDURIL)
return 0;
if (wizard || peek)
msg_print("Anduril");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_ANDURIL;
t_ptr->tohit = 10;
t_ptr->todam = 15;
t_ptr->flags = (TR_SEE_INVIS | TR_SLAY_EVIL | TR_FREE_ACT |
TR_SUST_STAT | TR_STR | TR_RES_FIRE | TR_FLAME_TONGUE);
t_ptr->flags2 |= (TR_SLAY_TROLL | TR_ACTIVATE | TR_SLAY_ORC | TR_ARTIFACT);
t_ptr->p1 = 4;
t_ptr->toac = 5;
t_ptr->cost = 80000L;
ANDURIL = 1;
return 1;
case 5:
case 6:
case 7:
case 8:
if (ANGUIREL)
return 0;
if (wizard || peek)
msg_print("Anguirel");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_ANGUIREL;
t_ptr->tohit = 8;
t_ptr->todam = 12;
t_ptr->flags = (TR_SEE_INVIS | TR_SLAY_EVIL | TR_FREE_ACT | TR_RES_LIGHT
| TR_STR | TR_CON);
t_ptr->flags2 |= (TR_ARTIFACT |
TR_LIGHTNING | TR_LIGHT | TR_SLAY_DEMON | TR_RES_LT);
t_ptr->p1 = 2;
t_ptr->cost = 40000L;
ANGUIREL = 1;
return 1;
default:
if (ELVAGIL)
return 0;
if (wizard || peek)
msg_print("Elvagil");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_ELVAGIL;
t_ptr->ident |= ID_NOSHOW_TYPE;
t_ptr->tohit = 2;
t_ptr->todam = 7;
t_ptr->flags |= (TR_SEE_INVIS | TR_CHR | TR_DEX | TR_STEALTH | TR_FFALL);
t_ptr->flags2 |= (TR_SLAY_TROLL | TR_SLAY_ORC | TR_ARTIFACT);
t_ptr->p1 = 2;
t_ptr->cost = 30000L;
ELVAGIL = 1;
return 1;
}
} else if (!stricmp("& Two-Handed Sword", name)) {
switch (randint(8)) {
case 1:
case 2:
if (GURTHANG)
return 0;
if (wizard || peek)
msg_print("Gurthang");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_GURTHANG;
t_ptr->tohit = 13;
t_ptr->todam = 17;
t_ptr->flags = (TR_REGEN | TR_SLAY_X_DRAGON | TR_STR |
TR_FREE_ACT | TR_SLOW_DIGEST);
t_ptr->flags2 |= (TR_SLAY_TROLL | TR_ARTIFACT);
t_ptr->p1 = 2;
t_ptr->cost = 100000L;
GURTHANG = 1;
return 1;
case 3:
if (ZARCUTHRA)
return 0;
if (randint(3) > 1)
return 0;
if (wizard || peek)
msg_print("Zarcuthra");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_ZARCUTHRA;
t_ptr->ident |= ID_NOSHOW_TYPE;
t_ptr->tohit = 19;
t_ptr->todam = 21;
t_ptr->flags = (TR_SLAY_X_DRAGON | TR_STR | TR_SLAY_EVIL | TR_SLAY_ANIMAL |
TR_SLAY_UNDEAD | TR_AGGRAVATE | TR_CHR | TR_FLAME_TONGUE |
TR_SEE_INVIS | TR_RES_FIRE | TR_FREE_ACT | TR_INFRA);
t_ptr->flags2 |= (TR_ARTIFACT | TR_SLAY_TROLL | TR_SLAY_ORC | TR_SLAY_GIANT
| TR_SLAY_DEMON | TR_RES_CHAOS);
t_ptr->p1 = 4;
t_ptr->damage[0] = 6;
t_ptr->damage[1] = 4;
t_ptr->cost = 200000L;
ZARCUTHRA = 1;
return 1;
default:
if (MORMEGIL)
return 0;
if (wizard || peek)
msg_print("Mormegil");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_MORMEGIL;
t_ptr->tohit = -40;
t_ptr->todam = -60;
t_ptr->flags = (TR_SPEED | TR_AGGRAVATE | TR_CURSED);
t_ptr->flags2 |= (TR_ARTIFACT);
t_ptr->p1 = -1;
t_ptr->toac = -50;
t_ptr->cost = 10000L;
MORMEGIL = 1;
return 1;
}
} else if (!stricmp("& Broadsword", name)) {
switch (randint(12)) {
case 1:
case 2:
if (ARUNRUTH)
return 0;
if (wizard || peek)
msg_print("Arunruth");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_ARUNRUTH;
t_ptr->tohit = 20;
t_ptr->todam = 12;
t_ptr->damage[0] = 3;
t_ptr->flags = (TR_FFALL | TR_DEX |
TR_FREE_ACT | TR_SLOW_DIGEST);
t_ptr->flags2 |= (TR_SLAY_DEMON | TR_SLAY_ORC | TR_ACTIVATE | TR_ARTIFACT);
t_ptr->p1 = 4;
t_ptr->cost = 50000L;
ARUNRUTH = 1;
return 1;
case 3:
case 4:
case 5:
case 6:
if (GLAMDRING)
return 0;
if (wizard || peek)
msg_print("Glamdring");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_GLAMDRING;
t_ptr->tohit = 10;
t_ptr->todam = 15;
t_ptr->flags = (TR_SLAY_EVIL | TR_SLOW_DIGEST | TR_SEARCH | TR_FLAME_TONGUE |
TR_RES_FIRE);
t_ptr->flags2 |= (TR_ARTIFACT | TR_SLAY_ORC | TR_LIGHT | TR_RES_LT);
t_ptr->p1 = 3;
t_ptr->cost = 40000L;
GLAMDRING = 1;
return 1;
case 7:
if (AEGLIN)
return 0;
if (wizard || peek)
msg_print("Aeglin");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_AEGLIN;
t_ptr->tohit = 12;
t_ptr->todam = 16;
t_ptr->flags = (TR_SLOW_DIGEST | TR_SEARCH | TR_RES_LIGHT);
t_ptr->flags2 |= (TR_ARTIFACT | TR_SLAY_ORC | TR_LIGHT | TR_LIGHTNING);
t_ptr->p1 = 4;
t_ptr->cost = 45000L;
AEGLIN = 1;
return 1;
default:
if (ORCRIST)
return 0;
if (wizard || peek)
msg_print("Orcrist");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_ORCRIST;
t_ptr->tohit = 10;
t_ptr->todam = 15;
t_ptr->flags = (TR_SLAY_EVIL | TR_SLOW_DIGEST | TR_STEALTH | TR_FROST_BRAND |
TR_RES_COLD);
t_ptr->flags2 |= (TR_ARTIFACT | TR_SLAY_ORC | TR_LIGHT);
t_ptr->p1 = 3;
t_ptr->cost = 40000L;
ORCRIST = 1;
return 1;
}
} else if (!stricmp("& Bastard Sword", name)) {
if (CALRIS)
return 0;
if (wizard || peek)
msg_print("Calris");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_CALRIS;
t_ptr->tohit = -20;
t_ptr->todam = 20;
t_ptr->damage[0] = 3;
t_ptr->damage[1] = 7;
t_ptr->flags = (TR_SLAY_X_DRAGON | TR_CON | TR_AGGRAVATE |
TR_CURSED | TR_SLAY_EVIL);
t_ptr->flags2 |= (TR_SLAY_DEMON | TR_SLAY_TROLL | TR_RES_DISENCHANT
| TR_ARTIFACT);
t_ptr->p1 = 5;
t_ptr->cost = 100000L;
CALRIS = 1;
return 1;
} else if (!stricmp("& Main Gauche", name)) {
if (randint(4) > 1)
return 0;
if (MAEDHROS)
return 0;
if (wizard || peek)
msg_print("Maedhros");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_MAEDHROS;
t_ptr->tohit = 12;
t_ptr->todam = 15;
t_ptr->damage[0] = 2;
t_ptr->damage[1] = 6;
t_ptr->flags = (TR_DEX | TR_INT | TR_FREE_ACT | TR_SEE_INVIS);
t_ptr->flags2 |= (TR_ARTIFACT | TR_SLAY_GIANT | TR_SLAY_TROLL);
t_ptr->p1 = 3;
t_ptr->cost = 20000L;
MAEDHROS = 1;
return 1;
} else if (!stricmp("& Glaive", name)) {
if (randint(3) > 1)
return 0;
if (PAIN)
return 0;
if (wizard || peek)
msg_print("Pain!");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_PAIN;
t_ptr->tohit = 0;
t_ptr->todam = 30;
t_ptr->damage[0] = 10;
t_ptr->damage[1] = 6;
t_ptr->flags2 |= (TR_ARTIFACT);
t_ptr->cost = 50000L;
PAIN = 1;
return 1;
} else if (!stricmp("& Halberd", name)) {
if (OSONDIR)
return 0;
if (wizard || peek)
msg_print("Osondir");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_OSONDIR;
t_ptr->tohit = 6;
t_ptr->todam = 9;
t_ptr->flags = (TR_FLAME_TONGUE | TR_SLAY_UNDEAD | TR_RES_FIRE |
TR_FFALL | TR_CHR | TR_SEE_INVIS);
t_ptr->flags2 |= (TR_ARTIFACT | TR_RES_SOUND | TR_SLAY_GIANT);
t_ptr->p1 = 3;
t_ptr->cost = 22000L;
OSONDIR = 1;
return 1;
} else if (!stricmp("& Lucerne Hammer", name)) {
if (randint(2) > 1)
return 0;
if (TURMIL)
return 0;
if (wizard || peek)
msg_print("Turmil");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_TURMIL;
t_ptr->ident |= ID_NOSHOW_TYPE;
t_ptr->tohit = 10;
t_ptr->todam = 6;
t_ptr->flags = (TR_WIS | TR_REGEN | TR_FROST_BRAND | TR_RES_COLD | TR_INFRA);
t_ptr->flags2 |= (TR_ARTIFACT | TR_SLAY_ORC | TR_LIGHT |
TR_ACTIVATE | TR_RES_LT);
t_ptr->p1 = 4;
t_ptr->cost = 30000L;
t_ptr->toac = 8;
TURMIL = 1;
return 1;
} else if (!stricmp("& Pike", name)) {
if (randint(2) > 1)
return 0;
if (TIL)
return 0;
if (wizard || peek)
msg_print("Til-i-arc");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_TIL;
t_ptr->tohit = 10;
t_ptr->todam = 12;
t_ptr->toac = 10;
t_ptr->flags = (TR_FROST_BRAND | TR_FLAME_TONGUE | TR_RES_FIRE | TR_RES_COLD |
TR_SLOW_DIGEST | TR_INT | TR_SUST_STAT);
t_ptr->flags2 |= (TR_ARTIFACT | TR_SLAY_DEMON | TR_SLAY_GIANT | TR_SLAY_TROLL);
t_ptr->p1 = 2;
t_ptr->cost = 32000L;
TIL = 1;
return 1;
} else if (!stricmp("& Mace of Disruption", name)) {
if (randint(5) > 1)
return 0;
if (DEATHWREAKER)
return 0;
if (wizard || peek)
msg_print("Deathwreaker");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_DEATHWREAKER;
t_ptr->tohit = 18;
t_ptr->todam = 18;
t_ptr->damage[1] = 12;
t_ptr->flags = (TR_STR | TR_FLAME_TONGUE | TR_SLAY_EVIL | TR_SLAY_DRAGON |
TR_SLAY_ANIMAL | TR_TUNNEL | TR_AGGRAVATE | TR_RES_FIRE);
t_ptr->flags2 |= (TR_ARTIFACT | TR_IM_FIRE | TR_RES_CHAOS
| TR_RES_DISENCHANT | TR_RES_DARK);
t_ptr->p1 = 6;
t_ptr->cost = 400000L;
DEATHWREAKER = 1;
return 1;
} else if (!stricmp("& Scythe", name)) {
if (AVAVIR)
return 0;
if (wizard || peek)
msg_print("Avavir");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_AVAVIR;
t_ptr->tohit = 8;
t_ptr->todam = 8;
t_ptr->toac = 10;
t_ptr->flags = (TR_DEX | TR_CHR | TR_FREE_ACT | TR_RES_FIRE | TR_RES_COLD |
TR_SEE_INVIS | TR_FLAME_TONGUE | TR_FROST_BRAND);
t_ptr->flags2 |= (TR_ARTIFACT | TR_LIGHT | TR_ACTIVATE | TR_RES_LT);
t_ptr->p1 = 3;
t_ptr->cost = 18000L;
AVAVIR = 1;
return 1;
} else if (!stricmp("& Mace", name)) {
if (randint(2) > 1)
return 0;
if (TARATOL)
return 0;
if (wizard || peek)
msg_print("Taratol");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_TARATOL;
t_ptr->tohit = 12;
t_ptr->todam = 12;
t_ptr->weight = 200;
t_ptr->damage[1] = 7;
t_ptr->flags = (TR_SLAY_X_DRAGON | TR_RES_LIGHT);
t_ptr->flags2 |= (TR_ARTIFACT | TR_LIGHTNING | TR_ACTIVATE | TR_RES_DARK);
t_ptr->cost = 20000L;
TARATOL = 1;
return 1;
} else if (!stricmp("& Lance", name)) {
if (randint(3) > 1)
return 0;
if (EORLINGAS)
return 0;
if (wizard || peek)
msg_print("Lance of Eorlingas");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_EORLINGAS;
t_ptr->tohit = 3;
t_ptr->todam = 21;
t_ptr->weight = 360;
t_ptr->flags |= (TR_SEE_INVIS | TR_SLAY_EVIL | TR_DEX);
t_ptr->flags2 |= (TR_SLAY_TROLL | TR_SLAY_ORC | TR_ARTIFACT);
t_ptr->p1 = 2;
t_ptr->damage[1] = 12;
t_ptr->cost = 55000L;
EORLINGAS = 1;
return 1;
} else if (!stricmp("& Broad Axe", name)) {
if (BARUKKHELED)
return 0;
if (wizard || peek)
msg_print("Barukkheled");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_BARUKKHELED;
t_ptr->tohit = 13;
t_ptr->todam = 19;
t_ptr->flags |= (TR_SEE_INVIS | TR_SLAY_EVIL | TR_CON);
t_ptr->flags2 |= (TR_SLAY_ORC | TR_SLAY_TROLL | TR_SLAY_GIANT | TR_ARTIFACT);
t_ptr->p1 = 3;
t_ptr->cost = 50000L;
BARUKKHELED = 1;
return 1;
} else if (!stricmp("& Trident", name)) {
switch (randint(3)) {
case 1:
case 2:
if (randint(3) > 1)
return 0;
if (WRATH)
return 0;
if (wizard || peek)
msg_print("Wrath");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_WRATH;
t_ptr->tohit = 16;
t_ptr->todam = 18;
t_ptr->weight = 300;
t_ptr->damage[0] = 3;
t_ptr->damage[1] = 9;
t_ptr->flags |= (TR_SEE_INVIS | TR_SLAY_EVIL | TR_STR | TR_DEX |
TR_SLAY_UNDEAD);
t_ptr->flags2 |= (TR_RES_DARK | TR_RES_LT | TR_ARTIFACT | TR_BLESS_BLADE);
t_ptr->p1 = 2;
t_ptr->cost = 90000L;
WRATH = 1;
return 1;
case 3:
if (randint(4) > 1)
return 0;
if (ULMO)
return 0;
if (wizard || peek)
msg_print("Ulmo");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_ULMO;
t_ptr->tohit = 15;
t_ptr->todam = 19;
t_ptr->damage[0] = 4;
t_ptr->damage[1] = 10;
t_ptr->flags = (TR_SEE_INVIS | TR_FREE_ACT | TR_DEX | TR_REGEN |
TR_SLOW_DIGEST | TR_SLAY_ANIMAL | TR_SLAY_DRAGON |
TR_RES_ACID);
t_ptr->flags2 |= (TR_IM_ACID | TR_HOLD_LIFE | TR_ACTIVATE
| TR_RES_NETHER | TR_ARTIFACT | TR_BLESS_BLADE);
t_ptr->p1 = 4;
t_ptr->cost = 120000L;
ULMO = 1;
return 1;
}
} else if (!stricmp("& Scimitar", name)) {
if (HARADEKKET)
return 0;
if (wizard || peek)
msg_print("Haradekket");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_HARADEKKET;
t_ptr->tohit = 9;
t_ptr->todam = 11;
t_ptr->flags |= (TR_SEE_INVIS | TR_SLAY_EVIL | TR_DEX | TR_SLAY_UNDEAD
| TR_SLAY_ANIMAL);
t_ptr->flags2 |= (TR_ARTIFACT | TR_ATTACK_SPD);
t_ptr->p1 = 2;
t_ptr->cost = 30000L;
HARADEKKET = 1;
return 1;
} else if (!stricmp("& Lochaber Axe", name)) {
if (MUNDWINE)
return 0;
if (wizard || peek)
msg_print("Mundwine");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_MUNDWINE;
t_ptr->tohit = 12;
t_ptr->todam = 17;
t_ptr->flags |= (TR_SLAY_EVIL | TR_RES_FIRE | TR_RES_COLD
| TR_RES_LIGHT | TR_RES_ACID);
t_ptr->flags2 |= (TR_ARTIFACT);
t_ptr->cost = 30000L;
MUNDWINE = 1;
return 1;
} else if (!stricmp("& Cutlass", name)) {
if (GONDRICAM)
return 0;
if (wizard || peek)
msg_print("Gondricam");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_GONDRICAM;
t_ptr->ident |= ID_NOSHOW_TYPE;
t_ptr->tohit = 10;
t_ptr->todam = 11;
t_ptr->flags |= (TR_SEE_INVIS | TR_FFALL | TR_REGEN | TR_STEALTH | TR_RES_FIRE |
TR_RES_COLD | TR_RES_ACID | TR_RES_LIGHT | TR_DEX);
t_ptr->flags2 |= (TR_ARTIFACT);
t_ptr->p1 = 3;
t_ptr->cost = 28000L;
GONDRICAM = 1;
return 1;
} else if (!stricmp("& Sabre", name)) {
if (CARETH)
return 0;
if (wizard || peek)
msg_print("Careth Asdriag");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_CARETH;
t_ptr->tohit = 6;
t_ptr->todam = 8;
t_ptr->flags |= (TR_SLAY_DRAGON | TR_SLAY_ANIMAL);
t_ptr->flags2 |= (TR_SLAY_GIANT | TR_SLAY_ORC | TR_SLAY_TROLL | TR_ARTIFACT |
TR_ATTACK_SPD);
t_ptr->p1 = 1;
t_ptr->cost = 25000L;
CARETH = 1;
return 1;
} else if (!stricmp("& Rapier", name)) {
if (FORASGIL)
return 0;
if (wizard || peek)
msg_print("Forasgil");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_FORASGIL;
t_ptr->tohit = 12;
t_ptr->todam = 19;
t_ptr->flags |= (TR_RES_COLD | TR_FROST_BRAND | TR_SLAY_ANIMAL);
t_ptr->flags2 |= (TR_LIGHT | TR_RES_LT | TR_ARTIFACT);
t_ptr->cost = 15000L;
FORASGIL = 1;
return 1;
} else if (!stricmp("& Executioner's Sword", name)) {
if (randint(2) > 1)
return 0;
if (CRISDURIAN)
return 0;
if (wizard || peek)
msg_print("Crisdurian");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_CRISDURIAN;
t_ptr->tohit = 18;
t_ptr->todam = 19;
t_ptr->flags |= (TR_SEE_INVIS | TR_SLAY_EVIL | TR_SLAY_UNDEAD | TR_SLAY_DRAGON);
t_ptr->flags2 |= (TR_SLAY_GIANT | TR_SLAY_ORC | TR_SLAY_TROLL | TR_ARTIFACT);
t_ptr->cost = 100000L;
CRISDURIAN = 1;
return 1;
} else if (!stricmp("& Flail", name)) {
if (TOTILA)
return 0;
if (wizard || peek)
msg_print("Totila");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_TOTILA;
t_ptr->tohit = 6;
t_ptr->todam = 8;
t_ptr->damage[1] = 9;
t_ptr->flags = (TR_STEALTH | TR_RES_FIRE | TR_FLAME_TONGUE | TR_SLAY_EVIL);
t_ptr->flags2 |= (TR_ARTIFACT | TR_ACTIVATE | TR_RES_CONF);
t_ptr->p1 = 2;
t_ptr->cost = 55000L;
TOTILA = 1;
return 1;
} else if (!stricmp("& Short sword", name)) {
if (GILETTAR)
return 0;
if (wizard || peek)
msg_print("Gilettar");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_GILETTAR;
t_ptr->tohit = 3;
t_ptr->todam = 7;
t_ptr->flags = (TR_REGEN | TR_SLOW_DIGEST | TR_SLAY_ANIMAL);
t_ptr->flags2 |= (TR_ARTIFACT | TR_ATTACK_SPD);
t_ptr->p1 = 2;
t_ptr->cost = 15000L;
GILETTAR = 1;
return 1;
} else if (!stricmp("& Katana", name)) {
if (randint(3) > 1)
return 0;
if (AGLARANG)
return 0;
if (wizard || peek)
msg_print("Aglarang");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_AGLARANG;
t_ptr->tohit = 0;
t_ptr->todam = 0;
t_ptr->damage[0] = 6;
t_ptr->damage[1] = 8;
t_ptr->weight = 50;
t_ptr->flags = (TR_DEX | TR_SUST_STAT);
t_ptr->flags2 |= (TR_ARTIFACT);
t_ptr->p1 = 5;
t_ptr->cost = 40000L;
AGLARANG = 1;
return 1;
} else if (!stricmp("& Spear", name)) {
switch (randint(6)) {
case 1:
if (AEGLOS)
return 0;
if (wizard || peek)
msg_print("Aeglos");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_AEGLOS;
t_ptr->tohit = 15;
t_ptr->todam = 25;
t_ptr->damage[0] = 1;
t_ptr->damage[1] = 20;
t_ptr->flags = (TR_WIS | TR_FROST_BRAND |
TR_RES_COLD | TR_FREE_ACT | TR_SLOW_DIGEST);
t_ptr->flags2 |= (TR_SLAY_TROLL | TR_SLAY_ORC | TR_ACTIVATE | TR_ARTIFACT |
TR_BLESS_BLADE);
t_ptr->toac = 5;
t_ptr->p1 = 4;
t_ptr->cost = 140000L;
AEGLOS = 1;
return 1;
case 2:
case 3:
case 4:
case 5:
if (NIMLOTH)
return 0;
if (wizard || peek)
msg_print("Nimloth");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_NIMLOTH;
t_ptr->tohit = 11;
t_ptr->todam = 13;
t_ptr->flags = (TR_FROST_BRAND | TR_RES_COLD | TR_SLAY_UNDEAD |
TR_SEE_INVIS | TR_STEALTH);
t_ptr->flags2 |= (TR_ARTIFACT);
t_ptr->p1 = 3;
t_ptr->cost = 30000L;
NIMLOTH = 1;
return 1;
case 6:
if (OROME)
return 0;
if (wizard || peek)
msg_print("Orome");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_OROME;
t_ptr->ident |= ID_NOSHOW_TYPE;
t_ptr->tohit = 15;
t_ptr->todam = 15;
t_ptr->flags = (TR_FLAME_TONGUE | TR_SEE_INVIS | TR_SEARCH | TR_INT |
TR_RES_FIRE | TR_FFALL | TR_INFRA);
t_ptr->flags2 |= (TR_ACTIVATE | TR_LIGHT | TR_SLAY_GIANT | TR_RES_LT
| TR_ARTIFACT | TR_BLESS_BLADE);
t_ptr->p1 = 4;
t_ptr->cost = 60000L;
OROME = 1;
return 1;
}
} else if (!stricmp("& Dagger", name)) {
switch (randint(11)) {
case 1:
if (ANGRIST)
return 0;
if (wizard || peek)
msg_print("Angrist");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_ANGRIST;
t_ptr->tohit = 10;
t_ptr->todam = 15;
t_ptr->damage[0] = 2;
t_ptr->damage[1] = 5;
t_ptr->flags = (TR_DEX | TR_SLAY_EVIL | TR_SUST_STAT |
TR_FREE_ACT);
t_ptr->flags2 |= (TR_SLAY_TROLL | TR_SLAY_ORC | TR_RES_DARK | TR_ARTIFACT);
t_ptr->toac = 5;
t_ptr->p1 = 4;
t_ptr->cost = 100000L;
ANGRIST = 1;
return 1;
case 2:
case 3:
if (NARTHANC)
return 0;
if (wizard || peek)
msg_print("Narthanc");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_NARTHANC;
t_ptr->tohit = 4;
t_ptr->todam = 6;
t_ptr->flags = (TR_FLAME_TONGUE | TR_RES_FIRE);
t_ptr->flags2 |= (TR_ACTIVATE | TR_ARTIFACT);
t_ptr->cost = 12000;
NARTHANC = 1;
return 1;
case 4:
case 5:
if (NIMTHANC)
return 0;
if (wizard || peek)
msg_print("Nimthanc");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_NIMTHANC;
t_ptr->tohit = 4;
t_ptr->todam = 6;
t_ptr->flags = (TR_FROST_BRAND | TR_RES_COLD);
t_ptr->flags2 |= (TR_ACTIVATE | TR_ARTIFACT);
t_ptr->cost = 11000L;
NIMTHANC = 1;
return 1;
case 6:
case 7:
if (DETHANC)
return 0;
if (wizard || peek)
msg_print("Dethanc");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_DETHANC;
t_ptr->tohit = 4;
t_ptr->todam = 6;
t_ptr->flags = (TR_RES_LIGHT);
t_ptr->flags2 |= (TR_ACTIVATE | TR_LIGHTNING | TR_ARTIFACT);
t_ptr->cost = 13000L;
DETHANC = 1;
return 1;
case 8:
case 9:
if (RILIA)
return 0;
if (wizard || peek)
msg_print("Rilia");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_RILIA;
t_ptr->tohit = 4;
t_ptr->todam = 3;
t_ptr->damage[0] = 2;
t_ptr->damage[1] = 4;
t_ptr->flags = TR_POISON;
t_ptr->flags2 |= (TR_ACTIVATE | TR_RES_DISENCHANT | TR_ARTIFACT);
t_ptr->cost = 15000L;
RILIA = 1;
return 1;
case 10:
case 11:
if (BELANGIL)
return 0;
if (wizard || peek)
msg_print("Belangil");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_BELANGIL;
t_ptr->tohit = 6;
t_ptr->todam = 9;
t_ptr->damage[0] = 3;
t_ptr->damage[1] = 2;
t_ptr->flags = (TR_FROST_BRAND | TR_RES_COLD | TR_REGEN | TR_SLOW_DIGEST |
TR_DEX | TR_SEE_INVIS);
t_ptr->flags2 |= (TR_ACTIVATE | TR_ARTIFACT);
t_ptr->p1 = 2;
t_ptr->cost = 40000L;
BELANGIL = 1;
return 1;
}
} else if (!stricmp("& Small sword", name)) {
if (STING)
return 0;
if (wizard || peek)
msg_print("Sting");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_STING;
t_ptr->tohit = 7;
t_ptr->todam = 8;
t_ptr->flags |= (TR_SEE_INVIS | TR_SLAY_EVIL |
TR_SLAY_UNDEAD | TR_DEX | TR_CON | TR_STR |
TR_FREE_ACT);
t_ptr->flags2 |= (TR_ARTIFACT | TR_SLAY_ORC | TR_LIGHT | TR_RES_LT |
TR_ATTACK_SPD);
t_ptr->p1 = 2;
t_ptr->cost = 100000L;
STING = 1;
return 1;
} else if (!stricmp("& Great Axe", name)) {
switch (randint(2)) {
case 1:
if (randint(6) > 1)
return 0;
if (DURIN)
return 0;
if (wizard || peek)
msg_print("Durin");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_DURIN;
t_ptr->tohit = 10;
t_ptr->todam = 20;
t_ptr->toac = 15;
t_ptr->flags = (TR_SLAY_X_DRAGON | TR_CON | TR_FREE_ACT |
TR_RES_FIRE | TR_RES_ACID);
t_ptr->flags2 |= (TR_SLAY_DEMON | TR_SLAY_TROLL | TR_SLAY_ORC | TR_RES_DARK
| TR_RES_LT | TR_RES_CHAOS | TR_ARTIFACT);
t_ptr->p1 = 3;
t_ptr->cost = 150000L;
DURIN = 1;
return 1;
case 2:
if (randint(8) > 1)
return 0;
if (EONWE)
return 0;
if (wizard || peek)
msg_print("Eonwe");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_EONWE;
t_ptr->tohit = 15;
t_ptr->todam = 18;
t_ptr->toac = 8;
t_ptr->flags = (TR_STATS | TR_SLAY_EVIL | TR_SLAY_UNDEAD | TR_FROST_BRAND |
TR_FREE_ACT | TR_SEE_INVIS | TR_RES_COLD);
t_ptr->flags2 |= (TR_IM_COLD | TR_SLAY_ORC | TR_ACTIVATE | TR_ARTIFACT |
TR_BLESS_BLADE);
t_ptr->p1 = 2;
t_ptr->cost = 200000L;
EONWE = 1;
return 1;
}
} else if (!stricmp("& Battle Axe", name)) {
switch (randint(2)) {
case 1:
if (BALLI)
return 0;
if (wizard || peek)
msg_print("Balli Stonehand");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_BALLI;
t_ptr->ident |= ID_NOSHOW_TYPE;
t_ptr->tohit = 8;
t_ptr->todam = 11;
t_ptr->damage[0] = 3;
t_ptr->damage[1] = 6;
t_ptr->toac = 5;
t_ptr->flags = (TR_FFALL | TR_RES_LIGHT | TR_SEE_INVIS | TR_STR | TR_CON
| TR_FREE_ACT | TR_RES_COLD | TR_RES_ACID
| TR_RES_FIRE | TR_REGEN | TR_STEALTH);
t_ptr->flags2 |= (TR_SLAY_DEMON | TR_SLAY_TROLL | TR_SLAY_ORC | TR_RES_BLIND
| TR_ARTIFACT);
t_ptr->p1 = 3;
t_ptr->cost = 90000L;
BALLI = 1;
return 1;
case 2:
if (LOTHARANG)
return 0;
if (wizard || peek)
msg_print("Lotharang");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_LOTHARANG;
t_ptr->tohit = 4;
t_ptr->todam = 3;
t_ptr->flags = (TR_STR | TR_DEX);
t_ptr->flags2 |= (TR_ACTIVATE | TR_SLAY_TROLL | TR_SLAY_ORC | TR_ARTIFACT);
t_ptr->p1 = 1;
t_ptr->cost = 21000L;
LOTHARANG = 1;
return 1;
}
} else if (!stricmp("& War Hammer", name)) {
if (randint(10) > 1)
return 0;
if (AULE)
return 0;
if (wizard || peek)
msg_print("Aule");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_AULE;
t_ptr->damage[0] = 5;
t_ptr->damage[1] = 5;
t_ptr->tohit = 19;
t_ptr->todam = 21;
t_ptr->toac = 5;
t_ptr->flags = (TR_SLAY_X_DRAGON | TR_SLAY_EVIL | TR_SLAY_UNDEAD |
TR_RES_FIRE | TR_RES_ACID | TR_RES_COLD | TR_RES_LIGHT |
TR_FREE_ACT | TR_SEE_INVIS | TR_WIS);
t_ptr->flags2 |= (TR_ARTIFACT | TR_SLAY_DEMON | TR_LIGHTNING | TR_RES_NEXUS);
t_ptr->p1 = 4;
t_ptr->cost = 250000L;
AULE = 1;
return 1;
} else if (!stricmp("& Beaked Axe", name)) {
if (randint(2) > 1)
return 0;
if (THEODEN)
return 0;
if (wizard || peek)
msg_print("Theoden");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_THEODEN;
t_ptr->tohit = 8;
t_ptr->todam = 10;
t_ptr->flags = (TR_WIS | TR_CON | TR_SEARCH | TR_SLOW_DIGEST | TR_SLAY_DRAGON);
t_ptr->flags2 |= (TR_TELEPATHY | TR_ACTIVATE | TR_ARTIFACT);
t_ptr->ident |= ID_NOSHOW_TYPE;
t_ptr->p1 = 3;
t_ptr->cost = 40000L;
THEODEN = 1;
return 1;
} else if (!stricmp("& Two-Handed Great Flail", name)) {
if (randint(5) > 1)
return 0;
if (THUNDERFIST)
return 0;
if (wizard || peek)
msg_print("Thunderfist");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_THUNDERFIST;
t_ptr->tohit = 5;
t_ptr->todam = 18;
t_ptr->flags = (TR_SLAY_ANIMAL | TR_STR | TR_FLAME_TONGUE |
TR_RES_FIRE | TR_RES_LIGHT);
t_ptr->flags2 |= (TR_ARTIFACT | TR_SLAY_TROLL | TR_SLAY_ORC
| TR_LIGHTNING | TR_RES_DARK);
t_ptr->p1 = 4;
t_ptr->cost = 160000L;
THUNDERFIST = 1;
return 1;
} else if (!stricmp("& Morningstar", name)) {
switch (randint(2)) {
case 1:
if (randint(2) > 1)
return 0;
if (BLOODSPIKE)
return 0;
if (wizard || peek)
msg_print("Bloodspike");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_BLOODSPIKE;
t_ptr->tohit = 8;
t_ptr->todam = 22;
t_ptr->flags = (TR_SLAY_ANIMAL | TR_STR | TR_SEE_INVIS);
t_ptr->flags2 |= (TR_ARTIFACT | TR_SLAY_TROLL | TR_SLAY_ORC | TR_RES_NEXUS);
t_ptr->p1 = 4;
t_ptr->cost = 30000L;
BLOODSPIKE = 1;
return 1;
case 2:
if (FIRESTAR)
return 0;
if (wizard || peek)
msg_print("Firestar");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_FIRESTAR;
t_ptr->tohit = 5;
t_ptr->todam = 7;
t_ptr->flags = (TR_FLAME_TONGUE | TR_RES_FIRE);
t_ptr->flags2 |= (TR_ACTIVATE | TR_ARTIFACT);
t_ptr->toac = 2;
t_ptr->cost = 35000L;
FIRESTAR = 1;
return 1;
}
} else if (!stricmp("& Blade of Chaos", name)) {
if (DOOMCALLER)
return 0;
if (randint(3) > 1)
return 0;
if (wizard || peek)
msg_print("Doomcaller");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_DOOMCALLER;
t_ptr->tohit = 18;
t_ptr->todam = 28;
t_ptr->flags = (TR_CON | TR_SLAY_ANIMAL | TR_SLAY_X_DRAGON |
TR_FROST_BRAND | TR_SLAY_EVIL | TR_FREE_ACT | TR_SEE_INVIS |
TR_RES_FIRE | TR_RES_COLD | TR_RES_LIGHT | TR_RES_ACID |
TR_AGGRAVATE);
t_ptr->flags2 |= (TR_SLAY_TROLL | TR_SLAY_ORC | TR_TELEPATHY | TR_ARTIFACT);
t_ptr->p1 = -5;
t_ptr->cost = 200000L;
DOOMCALLER = 1;
return 1;
} else if (!stricmp("& Quarterstaff", name)) {
switch (randint(7)) {
case 1:
case 2:
case 3:
if (NAR)
return 0;
if (wizard || peek)
msg_print("Nar-i-vagil");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_NAR;
t_ptr->tohit = 10;
t_ptr->todam = 20;
t_ptr->flags = (TR_INT | TR_SLAY_ANIMAL | TR_FLAME_TONGUE | TR_RES_FIRE);
t_ptr->flags2 |= (TR_ARTIFACT);
t_ptr->p1 = 3;
t_ptr->cost = 70000L;
NAR = 1;
return 1;
case 4:
case 5:
case 6:
if (ERIRIL)
return 0;
if (wizard || peek)
msg_print("Eriril");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_ERIRIL;
t_ptr->tohit = 3;
t_ptr->todam = 5;
t_ptr->flags = (TR_SLAY_EVIL | TR_SEE_INVIS | TR_INT | TR_WIS);
t_ptr->flags2 |= (TR_LIGHT | TR_ACTIVATE | TR_RES_LT | TR_ARTIFACT);
t_ptr->p1 = 4;
t_ptr->cost = 20000L;
ERIRIL = 1;
return 1;
case 7:
if (OLORIN)
return 0;
if (randint(2) > 1)
return 0;
if (wizard || peek)
msg_print("Olorin");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_OLORIN;
t_ptr->tohit = 10;
t_ptr->todam = 13;
t_ptr->damage[0] = 2;
t_ptr->damage[1] = 10;
t_ptr->flags = (TR_SLAY_EVIL | TR_SEE_INVIS | TR_WIS | TR_INT | TR_CHR
| TR_FLAME_TONGUE | TR_RES_FIRE);
t_ptr->flags2 |= (TR_ARTIFACT | TR_HOLD_LIFE | TR_SLAY_ORC | TR_SLAY_TROLL
| TR_ACTIVATE | TR_RES_NETHER);
t_ptr->p1 = 4;
t_ptr->cost = 130000L;
OLORIN = 1;
return 1;
}
}
return 0;
}
int
unique_armour(t_ptr)
inven_type *t_ptr;
{
const char *name;
if (be_nasty)
return 0;
name = object_list[t_ptr->index].name;
if (!strncmp("Adamantite", name, 10)) {
if (SOULKEEPER)
return 0;
if (randint(3) > 1)
return 0;
if (wizard || peek)
msg_print("Soulkeeper");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_RES_ACID | TR_RES_COLD);
t_ptr->flags2 |= (TR_HOLD_LIFE | TR_ACTIVATE | TR_RES_CHAOS | TR_RES_DARK |
TR_RES_NEXUS | TR_RES_NETHER | TR_ARTIFACT);
t_ptr->name2 = SN_SOULKEEPER;
t_ptr->toac = 20;
t_ptr->cost = 300000L;
SOULKEEPER = 1;
return 1;
}
/* etc..... */
else if (!strncmp("Multi-Hued", name, 10)) {
if (RAZORBACK)
return 0;
if (randint(3) > 1)
return 0;
if (wizard || peek)
msg_print("Razorback");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_RES_FIRE | TR_RES_COLD | TR_RES_ACID | TR_POISON |
TR_RES_LIGHT | TR_FREE_ACT | TR_SEE_INVIS | TR_INT |
TR_WIS | TR_STEALTH | TR_AGGRAVATE);
t_ptr->flags2 |= (TR_ACTIVATE | TR_LIGHT | TR_IM_LIGHT | TR_RES_LT |
TR_ARTIFACT);
t_ptr->ident |= ID_NOSHOW_TYPE;
t_ptr->toac = 25;
t_ptr->p1 = -2;
t_ptr->weight = 400;
t_ptr->ac = 30;
t_ptr->tohit = -3;
t_ptr->cost = 400000L;
t_ptr->name2 = SN_RAZORBACK;
RAZORBACK = 1;
return 1;
} else if (!strncmp("Power Drag", name, 10)) {
if (BLADETURNER)
return 0;
if (wizard || peek)
msg_print("Bladeturner");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_RES_FIRE | TR_RES_COLD | TR_RES_ACID | TR_POISON |
TR_RES_LIGHT | TR_DEX | TR_SEARCH | TR_REGEN);
t_ptr->flags2 |= (TR_HOLD_LIFE | TR_RES_CONF | TR_RES_SOUND | TR_RES_LT
| TR_RES_DARK | TR_RES_CHAOS | TR_RES_DISENCHANT | TR_ARTIFACT
| TR_RES_SHARDS | TR_RES_BLIND | TR_RES_NEXUS | TR_RES_NETHER
| TR_ACTIVATE);
t_ptr->ident |= ID_NOSHOW_TYPE;
t_ptr->toac = 35;
t_ptr->p1 = -3;
t_ptr->ac = 50;
t_ptr->tohit = -4;
t_ptr->weight = 500;
t_ptr->cost = 500000L;
t_ptr->name2 = SN_BLADETURNER;
BLADETURNER = 1;
return 1;
} else if (!stricmp("& Pair of Hard Leather Boots", name)) {
if (FEANOR)
return 0;
if (randint(5) > 1)
return 0;
if (wizard || peek)
msg_print("Feanor");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_RES_ACID | TR_SPEED | TR_STEALTH);
t_ptr->flags2 |= (TR_ACTIVATE | TR_RES_NEXUS | TR_ARTIFACT);
t_ptr->name2 = SN_FEANOR;
t_ptr->p1 = 1;
t_ptr->toac = 20;
t_ptr->cost = 130000L;
FEANOR = 1;
return 1;
} else if (!stricmp("& Pair of Soft Leather Boots", name)) {
if (DAL)
return 0;
if (wizard || peek)
msg_print("Dal-i-thalion");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_FREE_ACT | TR_DEX | TR_SUST_STAT | TR_RES_ACID);
t_ptr->flags2 |= (TR_ACTIVATE | TR_ARTIFACT | TR_RES_NETHER | TR_RES_CHAOS);
t_ptr->name2 = SN_DAL;
t_ptr->p1 = 5;
t_ptr->toac = 15;
t_ptr->cost = 40000L;
DAL = 1;
return 1;
} else if (!stricmp("& Small Metal Shield", name)) {
if (THORIN)
return 0;
if (randint(2) > 1)
return 0;
if (wizard || peek)
msg_print("Thorin");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_CON | TR_FREE_ACT | TR_STR |
TR_RES_ACID | TR_SEARCH);
t_ptr->flags2 |= (TR_RES_SOUND | TR_RES_CHAOS | TR_ARTIFACT | TR_IM_ACID);
t_ptr->name2 = SN_THORIN;
t_ptr->ident |= ID_NOSHOW_TYPE;
t_ptr->tohit = 0;
t_ptr->p1 = 4;
t_ptr->toac = 25;
t_ptr->cost = 60000L;
THORIN = 1;
return 1;
} else if (!stricmp("Full Plate Armour", name)) {
if (ISILDUR)
return 0;
if (wizard || peek)
msg_print("Isildur");
else
good_item_flag = TRUE;
t_ptr->weight = 300;
t_ptr->flags |= (TR_RES_ACID | TR_RES_FIRE | TR_RES_COLD | TR_RES_LIGHT);
t_ptr->flags2 |= (TR_RES_SOUND | TR_ARTIFACT | TR_RES_NEXUS);
t_ptr->name2 = SN_ISILDUR;
t_ptr->tohit = 0;
t_ptr->toac = 25;
t_ptr->cost = 40000L;
ISILDUR = 1;
return 1;
} else if (!stricmp("Metal Brigandine Armour", name)) {
if (ROHAN)
return 0;
if (wizard || peek)
msg_print("Rohirrim");
else
good_item_flag = TRUE;
t_ptr->weight = 200;
t_ptr->flags |= (TR_RES_ACID | TR_RES_FIRE | TR_RES_COLD | TR_RES_LIGHT |
TR_STR | TR_DEX);
t_ptr->flags2 |= (TR_RES_SOUND | TR_RES_CONF | TR_ARTIFACT);
t_ptr->name2 = SN_ROHAN;
t_ptr->tohit = 0;
t_ptr->p1 = 2;
t_ptr->toac = 15;
t_ptr->cost = 30000L;
ROHAN = 1;
return 1;
} else if (!stricmp("& Large Metal Shield", name)) {
if (ANARION)
return 0;
if (randint(3) > 1)
return 0;
else
good_item_flag = TRUE;
if (wizard || peek)
msg_print("Anarion");
t_ptr->flags |= (TR_RES_ACID | TR_RES_FIRE | TR_RES_COLD | TR_RES_LIGHT |
TR_SUST_STAT);
t_ptr->flags2 |= (TR_ARTIFACT);
t_ptr->name2 = SN_ANARION;
t_ptr->p1 = 10;
t_ptr->ident |= ID_NOSHOW_P1;
t_ptr->tohit = 0;
t_ptr->toac = 20;
t_ptr->cost = 160000L;
ANARION = 1;
return 1;
} else if (!stricmp("& Set of Cesti", name)) {
if (FINGOLFIN)
return 0;
if (randint(3) > 1)
return 0;
if (wizard || peek)
msg_print("Fingolfin");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_RES_ACID | TR_DEX | TR_FREE_ACT);
t_ptr->flags2 |= (TR_ACTIVATE | TR_ARTIFACT);
t_ptr->name2 = SN_FINGOLFIN;
t_ptr->ident |= ID_SHOW_HITDAM;
t_ptr->p1 = 4;
t_ptr->tohit = 10;
t_ptr->todam = 10;
t_ptr->toac = 20;
t_ptr->cost = 110000L;
FINGOLFIN = 1;
return 1;
} else if (!stricmp("& Set of Leather Gloves", name)) {
if (randint(3) == 1) {
if (CAMBELEG)
return 0;
if (wizard || peek)
msg_print("Cambeleg");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_STR | TR_CON | TR_FREE_ACT);
t_ptr->flags2 |= (TR_ARTIFACT);
t_ptr->name2 = SN_CAMBELEG;
t_ptr->ident |= ID_SHOW_HITDAM;
t_ptr->p1 = 2;
t_ptr->tohit = 8;
t_ptr->todam = 8;
t_ptr->toac = 15;
t_ptr->cost = 36000L;
CAMBELEG = 1;
return 1;
} else {
if (CAMMITHRIM)
return 0;
if (wizard || peek)
msg_print("Cammithrim");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_SUST_STAT | TR_FREE_ACT);
t_ptr->flags2 |= (TR_ACTIVATE | TR_LIGHT | TR_RES_LT | TR_ARTIFACT);
t_ptr->name2 = SN_CAMMITHRIM;
t_ptr->ident |= ID_NOSHOW_P1;
t_ptr->p1 = 5;
t_ptr->toac = 10;
t_ptr->cost = 30000L;
CAMMITHRIM = 1;
return 1;
}
} else if (!stricmp("& Set of Gauntlets", name)) {
switch (randint(6)) {
case 1:
if (PAURHACH)
return 0;
if (wizard || peek)
msg_print("Paurhach");
else
good_item_flag = TRUE;
t_ptr->flags |= TR_RES_FIRE;
t_ptr->flags2 |= (TR_ACTIVATE | TR_ARTIFACT);
t_ptr->name2 = SN_PAURHACH;
t_ptr->toac = 15;
t_ptr->cost = 15000L;
PAURHACH = 1;
return 1;
case 2:
if (PAURNIMMEN)
return 0;
if (wizard || peek)
msg_print("Paurnimmen");
else
good_item_flag = TRUE;
t_ptr->flags |= TR_RES_COLD;
t_ptr->flags2 |= (TR_ACTIVATE | TR_ARTIFACT);
t_ptr->name2 = SN_PAURNIMMEN;
t_ptr->toac = 15;
t_ptr->cost = 13000L;
PAURNIMMEN = 1;
return 1;
case 3:
if (PAURAEGEN)
return 0;
if (wizard || peek)
msg_print("Pauraegen");
else
good_item_flag = TRUE;
t_ptr->flags |= TR_RES_LIGHT;
t_ptr->flags2 |= (TR_ACTIVATE | TR_ARTIFACT);
t_ptr->name2 = SN_PAURAEGEN;
t_ptr->toac = 15;
t_ptr->cost = 11000L;
PAURAEGEN = 1;
return 1;
case 4:
if (PAURNEN)
return 0;
if (wizard || peek)
msg_print("Paurnen");
else
good_item_flag = TRUE;
t_ptr->flags |= TR_RES_ACID;
t_ptr->flags2 |= (TR_ACTIVATE | TR_ARTIFACT);
t_ptr->name2 = SN_PAURNEN;
t_ptr->toac = 15;
t_ptr->cost = 12000L;
PAURNEN = 1;
return 1;
default:
if (CAMLOST)
return 0;
if (wizard || peek)
msg_print("Camlost");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_STR | TR_DEX | TR_AGGRAVATE | TR_CURSED);
t_ptr->flags2 |= (TR_ARTIFACT);
t_ptr->name2 = SN_CAMLOST;
t_ptr->toac = 0;
t_ptr->p1 = -5;
t_ptr->tohit = -11;
t_ptr->todam = -12;
t_ptr->ident |= (ID_SHOW_HITDAM/* | ID_SHOW_P1*/);
t_ptr->cost = 0L;
CAMLOST = 1;
return 1;
}
} else if (!stricmp("Mithril Chain Mail", name)) {
if (BELEGENNON)
return 0;
if (wizard || peek)
msg_print("Belegennon");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_RES_ACID | TR_RES_FIRE | TR_RES_COLD |
TR_RES_LIGHT | TR_STEALTH);
t_ptr->flags2 |= (TR_ACTIVATE | TR_ARTIFACT);
t_ptr->name2 = SN_BELEGENNON;
t_ptr->p1 = 4;
t_ptr->toac = 20;
t_ptr->cost = 105000L;
BELEGENNON = 1;
return 1;
} else if (!stricmp("Mithril Plate Mail", name)) {
if (CELEBORN)
return 0;
if (wizard || peek)
msg_print("Celeborn");
else
good_item_flag = TRUE;
t_ptr->weight = 250;
t_ptr->flags |= (TR_RES_ACID | TR_RES_FIRE | TR_RES_COLD | TR_RES_LIGHT |
TR_STR | TR_CHR);
t_ptr->flags2 |= (TR_ACTIVATE | TR_RES_DISENCHANT | TR_RES_DARK | TR_ARTIFACT);
t_ptr->name2 = SN_CELEBORN;
t_ptr->p1 = 4;
t_ptr->toac = 25;
t_ptr->cost = 150000L;
CELEBORN = 1;
return 1;
} else if (!stricmp("Augmented Chain Mail", name)) {
if (randint(3) > 1)
return 0;
if (CASPANION)
return 0;
if (wizard || peek)
msg_print("Caspanion");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_RES_ACID | TR_POISON | TR_CON | TR_WIS | TR_INT);
t_ptr->flags2 |= (TR_RES_CONF | TR_ACTIVATE | TR_ARTIFACT);
t_ptr->name2 = SN_CASPANION;
t_ptr->p1 = 3;
t_ptr->toac = 20;
t_ptr->cost = 40000L;
CASPANION = 1;
return 1;
} else if (!stricmp("Soft Leather Armour", name)) {
if (HITHLOMIR)
return 0;
if (wizard || peek)
msg_print("Hithlomir");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_RES_ACID | TR_RES_FIRE | TR_RES_COLD | TR_RES_LIGHT |
TR_STEALTH);
t_ptr->flags2 |= (TR_ARTIFACT | TR_RES_DARK);
t_ptr->name2 = SN_HITHLOMIR;
t_ptr->p1 = 4;
t_ptr->toac = 20;
t_ptr->cost = 45000L;
HITHLOMIR = 1;
return 1;
} else if (!stricmp("Leather Scale Mail", name)) {
if (THALKETTOTH)
return 0;
if (wizard || peek)
msg_print("Thalkettoth");
else
good_item_flag = TRUE;
t_ptr->weight = 60;
t_ptr->flags |= (TR_RES_ACID | TR_DEX);
t_ptr->flags2 |= (TR_ARTIFACT | TR_RES_SHARDS);
t_ptr->name2 = SN_THALKETTOTH;
t_ptr->toac = 25;
t_ptr->p1 = 3;
t_ptr->cost = 25000L;
THALKETTOTH = 1;
return 1;
} else if (!stricmp("Chain Mail", name)) {
if (ARVEDUI)
return 0;
if (wizard || peek)
msg_print("Arvedui");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_RES_ACID | TR_RES_FIRE | TR_RES_COLD | TR_RES_LIGHT |
TR_STR | TR_CHR);
t_ptr->flags2 |= (TR_ARTIFACT | TR_RES_NEXUS | TR_RES_SHARDS);
t_ptr->name2 = SN_ARVEDUI;
t_ptr->p1 = 2;
t_ptr->toac = 15;
t_ptr->cost = 32000L;
ARVEDUI = 1;
return 1;
} else if (!stricmp("& Hard Leather Cap", name)) {
if (THRANDUIL)
return 0;
if (wizard || peek)
msg_print("Thranduil");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_RES_ACID | TR_INT | TR_WIS);
t_ptr->flags2 |= (TR_TELEPATHY | TR_RES_BLIND | TR_ARTIFACT);
t_ptr->name2 = SN_THRANDUIL;
t_ptr->p1 = 2;
t_ptr->toac = 10;
t_ptr->cost = 50000L;
THRANDUIL = 1;
return 1;
} else if (!stricmp("& Metal Cap", name)) {
if (THENGEL)
return 0;
if (wizard || peek)
msg_print("Thengel");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_RES_ACID | TR_WIS | TR_CHR);
t_ptr->flags2 |= (TR_ARTIFACT);
t_ptr->name2 = SN_THENGEL;
t_ptr->p1 = 3;
t_ptr->toac = 12;
t_ptr->cost = 22000L;
THENGEL = 1;
return 1;
} else if (!stricmp("& Steel Helm", name)) {
if (HAMMERHAND)
return 0;
if (wizard || peek)
msg_print("Hammerhand");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_STR | TR_CON | TR_DEX | TR_RES_ACID);
t_ptr->flags2 |= (TR_ARTIFACT | TR_RES_NEXUS);
t_ptr->name2 = SN_HAMMERHAND;
t_ptr->p1 = 3;
t_ptr->toac = 20;
t_ptr->cost = 45000L;
HAMMERHAND = 1;
return 1;
} else if (!stricmp("& Large Leather Shield", name)) {
if (CELEGORM)
return 0;
if (wizard || peek)
msg_print("Celegorm");
else
good_item_flag = TRUE;
t_ptr->weight = 60;
t_ptr->flags |= (TR_RES_ACID | TR_RES_FIRE | TR_RES_COLD | TR_RES_LIGHT);
t_ptr->flags2 |= (TR_RES_LT | TR_RES_DARK | TR_ARTIFACT);
t_ptr->name2 = SN_CELEGORM;
t_ptr->toac = 20;
t_ptr->cost = 12000L;
CELEGORM = 1;
return 1;
} else if (!stricmp("& Pair of Metal Shod Boots", name)) {
if (THROR)
return 0;
if (wizard || peek)
msg_print("Thror");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_CON | TR_STR | TR_RES_ACID);
t_ptr->flags2 |= (TR_ARTIFACT);
t_ptr->name2 = SN_THROR;
t_ptr->p1 = 3;
t_ptr->toac = 20;
t_ptr->cost = 12000L;
THROR = 1;
return 1;
} else if (!stricmp("& Iron Helm", name)) {
if (randint(6) == 1) {
if (DOR_LOMIN)
return 0;
if (wizard || peek)
msg_print("Dor-Lomin");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_RES_ACID | TR_RES_FIRE | TR_RES_COLD | TR_RES_LIGHT |
TR_CON | TR_DEX | TR_STR | TR_SEE_INVIS);
t_ptr->flags2 |= (TR_TELEPATHY | TR_LIGHT | TR_RES_LT | TR_RES_BLIND
| TR_ARTIFACT);
t_ptr->name2 = SN_DOR_LOMIN;
t_ptr->p1 = 4;
t_ptr->toac = 20;
t_ptr->cost = 300000L;
DOR_LOMIN = 1;
return 1;
} else if (randint(2) == 1) {
if (HOLHENNETH)
return 0;
if (wizard || peek)
msg_print("Holhenneth");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_INT | TR_WIS | TR_SEE_INVIS | TR_SEARCH | TR_RES_ACID);
t_ptr->flags2 |= (TR_ACTIVATE | TR_RES_BLIND | TR_ARTIFACT);
t_ptr->name2 = SN_HOLHENNETH;
t_ptr->ident |= ID_NOSHOW_TYPE;
t_ptr->p1 = 2;
t_ptr->toac = 10;
t_ptr->cost = 100000L;
HOLHENNETH = 1;
return 1;
} else {
if (GORLIM)
return 0;
if (wizard || peek)
msg_print("Gorlim");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_INT | TR_WIS | TR_SEE_INVIS | TR_SEARCH | TR_CURSED
| TR_AGGRAVATE);
t_ptr->flags2 |= (TR_ARTIFACT);
t_ptr->name2 = SN_GORLIM;
t_ptr->ident |= ID_NOSHOW_TYPE;
t_ptr->p1 = -125;
t_ptr->toac = 10;
t_ptr->cost = 0L;
GORLIM = 1;
return 1;
}
} else if (!stricmp("& Golden Crown", name)) {
if (randint(3) > 1)
return 0;
if (GONDOR)
return 0;
if (wizard || peek)
msg_print("Gondor");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_GONDOR;
t_ptr->flags = (TR_STR | TR_CON | TR_WIS | TR_SEE_INVIS | TR_REGEN
| TR_RES_ACID | TR_RES_FIRE);
t_ptr->flags2 = (TR_ACTIVATE | TR_LIGHT | TR_RES_LT | TR_RES_BLIND |
TR_ARTIFACT);
t_ptr->p1 = 3;
t_ptr->toac = 15;
t_ptr->cost = 100000L;
GONDOR = 1;
return 1;
} else if (!stricmp("& Iron Crown", name)) {
if (BERUTHIEL)
return 0;
if (wizard || peek)
msg_print("Beruthiel");
else
good_item_flag = TRUE;
t_ptr->flags |= (TR_STR | TR_DEX | TR_CON |
TR_RES_ACID | TR_SEE_INVIS | TR_FREE_ACT | TR_CURSED);
t_ptr->flags2 |= (TR_TELEPATHY | TR_ARTIFACT);
t_ptr->name2 = SN_BERUTHIEL;
t_ptr->p1 = -125;
t_ptr->toac = 20;
t_ptr->cost = 10000L;
BERUTHIEL = 1;
return 1;
}
return 0;
}
void
give_1_hi_resist(t) /* JLS: gives one of the "new" resistances to */
register inven_type *t;
{
switch (randint(10)) {
case 1:
t->flags2 |= TR_RES_CONF;
break;
case 2:
t->flags2 |= TR_RES_SOUND;
break;
case 3:
t->flags2 |= TR_RES_LT;
break;
case 4:
t->flags2 |= TR_RES_DARK;
break;
case 5:
t->flags2 |= TR_RES_CHAOS;
break;
case 6:
t->flags2 |= TR_RES_DISENCHANT;
break;
case 7:
t->flags2 |= TR_RES_SHARDS;
break;
case 8:
t->flags2 |= TR_RES_NEXUS;
break;
case 9:
t->flags2 |= TR_RES_BLIND;
break;
case 10:
t->flags2 |= TR_RES_NETHER;
break;
}
}
/* Chance of treasure having magic abilities -RAK- */
/* Chance increases with each dungeon level */
void
magic_treasure(x, level, good, not_unique)
int x, level, good, not_unique;
{
register inven_type *t_ptr;
register int32u chance, special, cursed, i;
int32u tmp;
chance = OBJ_BASE_MAGIC + level;
if (chance > OBJ_BASE_MAX)
chance = OBJ_BASE_MAX;
special = chance / OBJ_DIV_SPECIAL;
cursed = (10 * chance) / OBJ_DIV_CURSED;
t_ptr = &t_list[x];
/*
* some objects appear multiple times in the object_list with different
* levels, this is to make the object occur more often, however, for
* consistency, must set the level of these duplicates to be the same as the
* object with the lowest level
*/
/* Depending on treasure type, it can have certain magical properties */
switch (t_ptr->tval) {
case TV_SHIELD:
case TV_HARD_ARMOR:
case TV_SOFT_ARMOR:
if ((t_ptr->index >= 389 && t_ptr->index <= 394)
|| (t_ptr->index >= 408 && t_ptr->index <= 409)
|| (t_ptr->index >= 415 && t_ptr->index <= 419)) {
int8u artifact = FALSE;
/* all DSM are enchanted, I guess -CFT */
t_ptr->toac += m_bonus(0, 5, level) + randint(5);
rating += 30;
if ((magik(chance) && magik(special)) || (good == 666)) {
t_ptr->toac += randint(5); /* even better... */
if ((randint(3) == 1 || good == 666) && !not_unique
&& unique_armour(t_ptr)) /* ...but is it an artifact? */
artifact = TRUE;
}
if (!artifact) { /* assume cost&mesg done if it was an
* artifact */
if (wizard || peek)
msg_print("Dragon Scale Mail");
t_ptr->cost += ((int32) t_ptr->toac * 500L);
}
}
/* end if is a DSM */
else if (magik(chance) || good) {
t_ptr->toac += randint(3) + m_bonus(0, 5, level);
if (!stricmp(object_list[t_ptr->index].name, "& Robe") &&
((magik(special) && randint(30) == 1)
|| (good == 666 && magik(special)))) {
t_ptr->flags |= (TR_RES_LIGHT | TR_RES_COLD | TR_RES_ACID |
TR_RES_FIRE | TR_SUST_STAT);
if (wizard || peek)
msg_print("Robe of the Magi");
rating += 30;
t_ptr->flags2 |= TR_HOLD_LIFE;
t_ptr->ident |= ID_NOSHOW_P1;
give_1_hi_resist(t_ptr); /* JLS */
t_ptr->p1 = 10;
t_ptr->toac += 10 + randint(5);
t_ptr->name2 = SN_MAGI;
t_ptr->cost = 10000L + (t_ptr->toac * 100);
} else if (magik(special) || good == 666)
switch (randint(9)) {
case 1:
if ((randint(3) == 1 || good == 666) && !not_unique &&
unique_armour(t_ptr))
break;
t_ptr->flags |= (TR_RES_LIGHT | TR_RES_COLD | TR_RES_ACID |
TR_RES_FIRE);
if (randint(3) == 1) {
if (peek)
msg_print("Elvenkind");
rating += 25;
give_1_hi_resist(t_ptr); /* JLS */
t_ptr->flags |= TR_STEALTH;
t_ptr->p1 = randint(3);
t_ptr->name2 = SN_ELVENKIND;
t_ptr->toac += 15;
t_ptr->cost += 15000L;
} else {
if (peek)
msg_print("Resist");
rating += 20;
t_ptr->name2 = SN_R;
t_ptr->toac += 8;
t_ptr->cost += 12500L;
}
break;
case 2: /* Resist Acid */
if ((randint(3) == 1 || good == 666) && !not_unique &&
unique_armour(t_ptr))
break;
if (!strncmp(object_list[t_ptr->index].name,
"Mithril", 7) ||
!strncmp(object_list[t_ptr->index].name,
"Adamantite", 10))
break;
if (peek)
msg_print("Resist Acid");
rating += 15;
t_ptr->flags |= TR_RES_ACID;
t_ptr->name2 = SN_RA;
t_ptr->cost += 1000L;
break;
case 3:
case 4: /* Resist Fire */
if ((randint(3) == 1 || good == 666) && !not_unique &&
unique_armour(t_ptr))
break;
if (peek)
msg_print("Resist Fire");
rating += 17;
t_ptr->flags |= TR_RES_FIRE;
t_ptr->name2 = SN_RF;
t_ptr->cost += 600L;
break;
case 5:
case 6: /* Resist Cold */
if ((randint(3) == 1 || good == 666) && !not_unique &&
unique_armour(t_ptr))
break;
if (peek)
msg_print("Resist Cold");
rating += 16;
t_ptr->flags |= TR_RES_COLD;
t_ptr->name2 = SN_RC;
t_ptr->cost += 600L;
break;
case 7:
case 8:
case 9: /* Resist Lightning */
if ((randint(3) == 1 || good == 666) && !not_unique &&
unique_armour(t_ptr))
break;
if (peek)
msg_print("Resist Lightning");
rating += 15;
t_ptr->flags |= TR_RES_LIGHT;
t_ptr->name2 = SN_RL;
t_ptr->cost += 500L;
break;
}
} else if (magik(cursed)) {
t_ptr->toac = -randint(3) - m_bonus(0, 10, level);
t_ptr->cost = 0L;
t_ptr->flags |= TR_CURSED;
}
break;
case TV_HAFTED:
case TV_POLEARM:
case TV_SWORD:
/* always show tohit/todam values if identified */
t_ptr->ident |= ID_SHOW_HITDAM;
if (magik(chance) || good) {
t_ptr->tohit += randint(3) + m_bonus(0, 10, level);
t_ptr->todam += randint(3) + m_bonus(0, 10, level);
/*
* the 3*special/2 is needed because weapons are not as common as
* before change to treasure distribution, this helps keep same
* number of ego weapons same as before, see also missiles
*/
if (magik(3*special/2)||good==666) { /* was 2 */
if (!stricmp("& Whip", object_list[t_ptr->index].name)
&& randint(2)==1) {
if (peek) msg_print("Whip of Fire");
rating += 20;
t_ptr->name2 = SN_FIRE;
t_ptr->flags |= (TR_FLAME_TONGUE | TR_RES_FIRE);
/* this should allow some WICKED whips -CFT */
while (randint(5*(int)t_ptr->damage[0])==1) {
t_ptr->damage[0]++;
t_ptr->cost += 2500;
t_ptr->cost *= 2;
}
t_ptr->tohit += 5;
t_ptr->todam += 5;
} else {
switch (randint(30)) { /* was 16 */
case 1: /* Holy Avenger */
if (((randint(2) == 1) || (good == 666))
&& !not_unique &&
unique_weapon(t_ptr))
break;
if (peek)
msg_print("Holy Avenger");
rating += 30;
t_ptr->flags |= (TR_SEE_INVIS | TR_SUST_STAT |
TR_SLAY_UNDEAD | TR_SLAY_EVIL | TR_WIS);
t_ptr->flags2 |= (TR_SLAY_DEMON | TR_BLESS_BLADE);
t_ptr->tohit += 5;
t_ptr->todam += 5;
t_ptr->toac += randint(4);
/* the value in p1 is used for strength increase */
/* p1 is also used for sustain stat */
t_ptr->p1 = randint(4);
t_ptr->name2 = SN_HA;
t_ptr->cost += t_ptr->p1 * 500;
t_ptr->cost += 10000L;
t_ptr->cost *= 2;
break;
case 2: /* Defender */
if (((randint(2) == 1) || (good == 666)) && !not_unique &&
unique_weapon(t_ptr))
break;
if (peek)
msg_print("Defender");
rating += 23;
t_ptr->flags |= (TR_FFALL | TR_RES_LIGHT | TR_SEE_INVIS
| TR_FREE_ACT | TR_RES_COLD | TR_RES_ACID
| TR_RES_FIRE | TR_REGEN | TR_STEALTH);
t_ptr->tohit += 3;
t_ptr->todam += 3;
t_ptr->toac += 5 + randint(5);
t_ptr->name2 = SN_DF;
/* the value in p1 is used for stealth */
t_ptr->p1 = randint(3);
t_ptr->cost += t_ptr->p1 * 500;
t_ptr->cost += 7500L;
t_ptr->cost *= 2;
break;
case 3:
case 4: /* Flame Tongue */
if (((randint(2) == 1) || (good == 666)) && !not_unique &&
unique_weapon(t_ptr))
break;
rating += 20;
t_ptr->flags |= (TR_FLAME_TONGUE | TR_RES_FIRE);
if (peek)
msg_print("Flame");
t_ptr->tohit += 2;
t_ptr->todam += 3;
t_ptr->name2 = SN_FT;
t_ptr->cost += 3000L;
break;
case 5:
case 6: /* Frost Brand */
if (((randint(2) == 1) || (good == 666)) && !not_unique &&
unique_weapon(t_ptr))
break;
if (peek)
msg_print("Frost");
rating += 20;
t_ptr->flags |= (TR_FROST_BRAND | TR_RES_COLD);
t_ptr->tohit += 2;
t_ptr->todam += 2;
t_ptr->name2 = SN_FB;
t_ptr->cost += 2200L;
break;
case 7:
case 8: /* Slay Animal */
t_ptr->flags |= TR_SLAY_ANIMAL;
rating += 15;
if (peek)
msg_print("Slay Animal");
t_ptr->tohit += 3;
t_ptr->todam += 3;
t_ptr->name2 = SN_SA;
t_ptr->cost += 2000L;
break;
case 9:
case 10: /* Slay Dragon */
t_ptr->flags |= TR_SLAY_DRAGON;
if (peek)
msg_print("Slay Dragon");
rating += 18;
t_ptr->tohit += 3;
t_ptr->todam += 3;
t_ptr->name2 = SN_SD;
t_ptr->cost += 4000L;
break;
case 11:
case 12: /* Slay Evil */
t_ptr->flags |= TR_SLAY_EVIL;
if (randint(3) == 1) {
t_ptr->flags |= (TR_WIS);
t_ptr->flags2 |= (TR_BLESS_BLADE);
t_ptr->p1 = m_bonus(0, 3, level);
t_ptr->cost += (200 * t_ptr->p1);
}
if (peek)
msg_print("Slay Evil");
rating += 18;
t_ptr->tohit += 3;
t_ptr->todam += 3;
t_ptr->name2 = SN_SE;
t_ptr->cost += 4000L;
break;
case 13:
case 14: /* Slay Undead */
t_ptr->flags |= (TR_SEE_INVIS | TR_SLAY_UNDEAD);
if (randint(3) == 1) {
t_ptr->flags2 |= (TR_HOLD_LIFE);
t_ptr->cost += 1000;
}
if (peek)
msg_print("Slay Undead");
rating += 18;
t_ptr->tohit += 2;
t_ptr->todam += 2;
t_ptr->name2 = SN_SU;
t_ptr->cost += 3000L;
break;
case 15:
case 16:
case 17: /* Slay Orc */
t_ptr->flags2 |= TR_SLAY_ORC;
if (peek)
msg_print("Slay Orc");
rating += 13;
t_ptr->tohit += 2;
t_ptr->todam += 2;
t_ptr->name2 = SN_SO;
t_ptr->cost += 1200L;
break;
case 18:
case 19:
case 20: /* Slay Troll */
t_ptr->flags2 |= TR_SLAY_TROLL;
if (peek)
msg_print("Slay Troll");
rating += 13;
t_ptr->tohit += 2;
t_ptr->todam += 2;
t_ptr->name2 = SN_ST;
t_ptr->cost += 1200L;
break;
case 21:
case 22:
case 23:
t_ptr->flags2 |= TR_SLAY_GIANT;
if (peek)
msg_print("Slay Giant");
rating += 14;
t_ptr->tohit += 2;
t_ptr->todam += 2;
t_ptr->name2 = SN_SG;
t_ptr->cost += 1200L;
break;
case 24:
case 25:
case 26:
t_ptr->flags2 |= TR_SLAY_DEMON;
if (peek)
msg_print("Slay Demon");
rating += 16;
t_ptr->tohit += 2;
t_ptr->todam += 2;
t_ptr->name2 = SN_SDEM;
t_ptr->cost += 1200L;
break;
case 27: /* of Westernesse */
if (((randint(2) == 1) || (good == 666)) && !not_unique &&
unique_weapon(t_ptr))
break;
if (peek)
msg_print("Westernesse");
rating += 20;
t_ptr->flags |= (TR_SEE_INVIS | TR_DEX | TR_CON | TR_STR |
TR_FREE_ACT);
t_ptr->flags2 |= TR_SLAY_ORC;
t_ptr->tohit += randint(5) + 3;
t_ptr->todam += randint(5) + 3;
t_ptr->p1 = 1;
t_ptr->cost += 10000L;
t_ptr->cost *= 2;
t_ptr->name2 = SN_WEST;
break;
case 28:
case 29: /* Blessed Blade -DGK */
if ((t_ptr->tval != TV_SWORD) &&
(t_ptr->tval != TV_POLEARM))
break;
if (peek)
msg_print("Blessed");
rating += 20;
t_ptr->flags = TR_WIS;
t_ptr->flags2 = TR_BLESS_BLADE;
t_ptr->tohit += 3;
t_ptr->todam += 3;
t_ptr->p1 = randint(3);
t_ptr->name2 = SN_BLESS_BLADE;
t_ptr->cost += t_ptr->p1 * 1000;
t_ptr->cost += 3000L;
break;
case 30: /* of Speed -DGK */
if (((randint(2) == 1) || (good == 666))
&& !not_unique && unique_weapon(t_ptr))
break;
if (wizard || peek)
msg_print("Weapon of Extra Attacks");
rating += 20;
t_ptr->tohit += randint(5);
t_ptr->todam += randint(3);
t_ptr->flags2 = TR_ATTACK_SPD;
if (t_ptr->weight <= 80)
t_ptr->p1 = randint(3);
else if (t_ptr->weight <= 130)
t_ptr->p1 = randint(2);
else
t_ptr->p1 = 1;
t_ptr->name2 = SN_ATTACKS;
t_ptr->cost += (t_ptr->p1 * 2000);
t_ptr->cost *= 2;
break;
}
}
}
} else if (magik(cursed)) {
t_ptr->tohit = (-randint(3) - m_bonus(1, 20, level));
t_ptr->todam = (-randint(3) - m_bonus(1, 20, level));
t_ptr->flags |= TR_CURSED;
if (level > (20 + randint(15)) && randint(10) == 1) {
t_ptr->name2 = SN_MORGUL;
t_ptr->flags |= (TR_SEE_INVIS | TR_AGGRAVATE);
t_ptr->tohit -= 15;
t_ptr->todam -= 15;
t_ptr->toac = -10;
t_ptr->weight += 100;
}
t_ptr->cost = 0L;
}
break;
case TV_BOW:
/* always show tohit/todam values if identified */
t_ptr->ident |= ID_SHOW_HITDAM;
if (magik(chance) || good) {
t_ptr->tohit = randint(3) + m_bonus(0, 10, level);
t_ptr->todam = randint(3) + m_bonus(0, 10, level);
switch (randint(15)) {
case 1: case 2: case 3:
if (((randint(3)==1)||(good==666)) && !not_unique &&
!stricmp(object_list[t_ptr->index].name, "& Long Bow") &&
(((i=randint(2))==1 && !BELEG) || (i==2 && !BARD))) {
switch (i) {
case 1:
if (BELEG)
break;
if (wizard || peek)
msg_print("Belthronding");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_BELEG;
t_ptr->ident |= ID_NOSHOW_TYPE;
t_ptr->subval = 4; /* make do x5 damage!! -CFT */
t_ptr->tohit = 20;
t_ptr->todam = 22;
t_ptr->p1 = 3;
t_ptr->flags |= (TR_STEALTH | TR_DEX);
t_ptr->flags2 |= (TR_ARTIFACT | TR_RES_DISENCHANT);
t_ptr->cost = 35000L;
BELEG = 1;
break;
case 2:
if (BARD)
break;
if (wizard || peek)
msg_print("Bard");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_BARD;
t_ptr->subval = 3; /* make do x4 damage!! -CFT */
t_ptr->tohit = 17;
t_ptr->todam = 19;
t_ptr->p1 = 3;
t_ptr->flags |= (TR_FREE_ACT | TR_DEX);
t_ptr->flags2 |= (TR_ARTIFACT);
t_ptr->cost = 20000L;
BARD = 1;
break;
}
break;
}
if (((randint(5) == 1) || (good == 666)) && !not_unique &&
!stricmp(object_list[t_ptr->index].name, "& Light Crossbow")
&& !CUBRAGOL) {
if (CUBRAGOL)
break;
if (wizard || peek)
msg_print("Cubragol");
t_ptr->name2 = SN_CUBRAGOL;
t_ptr->subval = 11;
t_ptr->tohit = 10;
t_ptr->todam = 14;
t_ptr->p1 = 1;
t_ptr->flags |= (TR_SPEED | TR_RES_FIRE);
t_ptr->flags2 |= (TR_ACTIVATE | TR_ARTIFACT);
t_ptr->cost = 38000L;
CUBRAGOL = 1;
break;
}
t_ptr->name2 = SN_MIGHT;
if (peek)
msg_print("Bow of Might");
rating += 15;
t_ptr->subval++; /* make it do an extra multiple of damage */
t_ptr->tohit += 5;
t_ptr->todam += 10;
break;
case 4: case 5: case 6: case 7: case 8:
t_ptr->name2 = SN_MIGHT;
if (peek) msg_print("Bow of Might");
rating += 11;
t_ptr->tohit += 5;
t_ptr->todam += 12;
break;
case 9: case 10: case 11: case 12:
case 13: case 14: case 15:
t_ptr->name2 = SN_ACCURACY;
rating += 11;
if (peek)
msg_print("Accuracy");
t_ptr->tohit += 12;
t_ptr->todam += 5;
break;
}
} else if (magik(cursed)) {
t_ptr->tohit = (-m_bonus(5, 30, level));
t_ptr->todam = (-m_bonus(5, 20, level)); /* add damage. -CJS- */
t_ptr->flags |= TR_CURSED;
t_ptr->cost = 0L;
}
break;
case TV_DIGGING:
/* always show tohit/todam values if identified */
t_ptr->ident |= ID_SHOW_HITDAM;
if (magik(chance) || (good == 666)) {
tmp = randint(3);
if (tmp == 1) {
t_ptr->p1 += m_bonus(0, 5, level);
}
if (tmp == 2) /* do not give additional plusses -CWS */
;
else {
/* a cursed digging tool */
t_ptr->p1 = (-m_bonus(1, 15, level));
t_ptr->cost = 0L;
t_ptr->flags |= TR_CURSED;
}
}
break;
case TV_GLOVES:
if (magik(chance) || good) {
t_ptr->toac = randint(3) + m_bonus(0, 10, level);
if ((((randint(2) == 1) && magik(5 * special / 2)) || (good == 666)) &&
!stricmp(object_list[t_ptr->index].name,
"& Set of Leather Gloves") &&
!not_unique && unique_armour(t_ptr));
else if ((((randint(4) == 1) && magik(special)) || (good == 666))
&& !stricmp(object_list[t_ptr->index].name,
"& Set of Gauntlets") &&
!not_unique && unique_armour(t_ptr));
else if ((((randint(5) == 1) && magik(special)) || (good == 666))
&& !stricmp(object_list[t_ptr->index].name,
"& Set of Cesti") &&
!not_unique && unique_armour(t_ptr));
/* don't forget cesti -CFT */
else if (magik(special) || (good == 666)) {
switch (randint(10)) {
case 1:
case 2:
case 3:
if (peek)
msg_print("Free action");
rating += 11;
t_ptr->flags |= TR_FREE_ACT;
t_ptr->name2 = SN_FREE_ACTION;
t_ptr->cost += 1000L;
break;
case 4:
case 5:
case 6:
t_ptr->ident |= ID_SHOW_HITDAM;
rating += 17;
if (peek)
msg_print("Slaying");
t_ptr->tohit += 1 + randint(4);
t_ptr->todam += 1 + randint(4);
t_ptr->name2 = SN_SLAYING;
t_ptr->cost += (t_ptr->tohit + t_ptr->todam) * 250;
break;
case 7:
case 8:
case 9:
t_ptr->name2 = SN_AGILITY;
if (peek)
msg_print("Agility");
rating += 14;
t_ptr->p1 = 2 + randint(2);
t_ptr->flags |= TR_DEX;
t_ptr->cost += (t_ptr->p1) * 400;
break;
case 10:
if (((randint(3) == 1) || (good == 666)) && !not_unique &&
unique_armour(t_ptr))
break;
if (peek)
msg_print("Power");
rating += 22;
t_ptr->name2 = SN_POWER;
t_ptr->p1 = 1 + randint(4);
t_ptr->tohit += 1 + randint(4);
t_ptr->todam += 1 + randint(4);
t_ptr->flags |= TR_STR;
t_ptr->ident |= ID_SHOW_HITDAM;
t_ptr->ident |= ID_NOSHOW_TYPE;
t_ptr->cost += (t_ptr->tohit + t_ptr->todam + t_ptr->p1) * 300;
break;
}
}
} else if (magik(cursed)) {
if (magik(special)) {
if (randint(2) == 1) {
t_ptr->flags |= TR_DEX;
t_ptr->name2 = SN_CLUMSINESS;
} else {
t_ptr->flags |= TR_STR;
t_ptr->name2 = SN_WEAKNESS;
}
t_ptr->p1 = (randint(3) - m_bonus(0, 10, level));
}
t_ptr->toac = (-m_bonus(1, 20, level));
t_ptr->flags |= TR_CURSED;
t_ptr->cost = 0;
}
break;
case TV_BOOTS:
if (magik(chance) || good) {
t_ptr->toac = randint(3) + m_bonus(1, 10, level);
if (magik(special) || (good == 666)) {
tmp = randint(12);
if (tmp == 1) {
if (!((randint(2) == 1) && !not_unique
&& unique_armour(t_ptr))) {
t_ptr->flags |= TR_SPEED;
if (wizard || peek)
msg_print("Boots of Speed");
t_ptr->name2 = SN_SPEED;
rating += 30;
t_ptr->p1 = 1;
t_ptr->cost += 300000L;
}
} else if (stricmp("& Pair of Metal Shod Boots",
object_list[t_ptr->index].name)) /* not metal */
if (tmp > 6) {
t_ptr->flags |= TR_FFALL;
rating += 7;
t_ptr->name2 = SN_SLOW_DESCENT;
t_ptr->cost += 250;
} else if (tmp < 5) {
t_ptr->flags |= TR_STEALTH;
rating += 16;
t_ptr->p1 = randint(3);
t_ptr->name2 = SN_STEALTH;
t_ptr->cost += 500;
} else { /* 5,6 */
t_ptr->flags |= TR_FREE_ACT;
rating += 15;
t_ptr->name2 = SN_FREE_ACTION;
t_ptr->cost += 500;
t_ptr->cost *= 2;
}
else
/* is metal boots, different odds since no stealth */
if (tmp < 5) {
t_ptr->flags |= TR_FREE_ACT;
rating += 15;
t_ptr->name2 = SN_FREE_ACTION;
t_ptr->cost += 500;
t_ptr->cost *= 2;
} else { /* tmp > 4 */
t_ptr->flags |= TR_FFALL;
rating += 7;
t_ptr->name2 = SN_SLOW_DESCENT;
t_ptr->cost += 250;
}
}
} else if (magik(cursed)) {
tmp = randint(3);
if (tmp == 1) {
t_ptr->flags |= TR_SPEED;
t_ptr->name2 = SN_SLOWNESS;
t_ptr->p1 = -1;
} else if (tmp == 2) {
t_ptr->flags |= TR_AGGRAVATE;
t_ptr->name2 = SN_NOISE;
} else {
t_ptr->name2 = SN_GREAT_MASS;
t_ptr->weight = t_ptr->weight * 5;
}
t_ptr->cost = 0;
t_ptr->toac = (-m_bonus(2, 20, level));
t_ptr->flags |= TR_CURSED;
}
break;
case TV_HELM: /* Helms */
if ((t_ptr->subval >= 6) && (t_ptr->subval <= 8)) {
/* give crowns a higher chance for magic */
chance += t_ptr->cost / 100;
special += special;
}
if (magik(chance) || good) {
t_ptr->toac = randint(3) + m_bonus(0, 10, level);
if (magik(special) || (good == 666)) {
if (t_ptr->subval < 6) {
tmp = randint(14);
if (tmp < 3) {
if (!((randint(2) == 1) && !not_unique &&
unique_armour(t_ptr))) {
if (peek)
msg_print("Intelligence");
t_ptr->p1 = randint(2);
rating += 13;
t_ptr->flags |= TR_INT;
t_ptr->name2 = SN_INTELLIGENCE;
t_ptr->cost += t_ptr->p1 * 500;
}
} else if (tmp < 6) {
if (!((randint(2) == 1) && !not_unique &&
unique_armour(t_ptr))) {
if (peek)
msg_print("Wisdom");
rating += 13;
t_ptr->p1 = randint(2);
t_ptr->flags |= TR_WIS;
t_ptr->name2 = SN_WISDOM;
t_ptr->cost += t_ptr->p1 * 500;
}
} else if (tmp < 10) {
if (!((randint(2) == 1) && !not_unique &&
unique_armour(t_ptr))) {
t_ptr->p1 = 1 + randint(4);
rating += 11;
t_ptr->flags |= TR_INFRA;
t_ptr->name2 = SN_INFRAVISION;
t_ptr->cost += t_ptr->p1 * 250;
}
} else if (tmp < 12) {
if (!((randint(2) == 1) && !not_unique &&
unique_armour(t_ptr))) {
if (peek)
msg_print("Light");
t_ptr->flags2 |= (TR_RES_LT | TR_LIGHT);
rating += 6;
t_ptr->name2 = SN_LIGHT;
t_ptr->cost += 500;
}
} else if (tmp < 14) {
if (!((randint(2) == 1) && !not_unique &&
unique_armour(t_ptr))) {
if (peek)
msg_print("Helm of Seeing");
t_ptr->flags |= TR_SEE_INVIS;
t_ptr->flags2 |= TR_RES_BLIND;
rating += 8;
t_ptr->name2 = SN_SEEING;
t_ptr->cost += 1000;
}
} else {
if (!((randint(2) == 1) && !not_unique &&
unique_armour(t_ptr))) {
if (peek)
msg_print("Telepathy");
rating += 20;
t_ptr->flags2 |= TR_TELEPATHY;
t_ptr->name2 = SN_TELEPATHY;
t_ptr->cost += 50000L;
}
}
} else {
switch (randint(6)) {
case 1:
if (!(((randint(2) == 1) || (good == 666)) &&
!not_unique && unique_armour(t_ptr))) {
if (peek)
msg_print("Crown of Might");
rating += 19;
t_ptr->p1 = randint(3);
t_ptr->flags |= (TR_FREE_ACT | TR_CON |
TR_DEX | TR_STR);
t_ptr->name2 = SN_MIGHT;
t_ptr->cost += 1000 + t_ptr->p1 * 500;
}
break;
case 2:
if (peek)
msg_print("Lordliness");
t_ptr->p1 = randint(3);
rating += 17;
t_ptr->flags |= (TR_CHR | TR_WIS);
t_ptr->name2 = SN_LORDLINESS;
t_ptr->cost += 1000 + t_ptr->p1 * 500;
break;
case 3:
if (peek)
msg_print("Crown of the Magi");
rating += 15;
t_ptr->p1 = randint(3);
t_ptr->flags |= (TR_RES_LIGHT | TR_RES_COLD
| TR_RES_ACID | TR_RES_FIRE | TR_INT);
t_ptr->name2 = SN_MAGI;
t_ptr->cost += 3000 + t_ptr->p1 * 500;
break;
case 4:
rating += 8;
if (peek)
msg_print("Beauty");
t_ptr->p1 = randint(4);
t_ptr->flags |= TR_CHR;
t_ptr->name2 = SN_BEAUTY;
t_ptr->cost += 750;
break;
case 5:
if (peek)
msg_print("Seeing");
rating += 8;
t_ptr->p1 = 5 * (1 + randint(4));
t_ptr->flags |= (TR_SEE_INVIS | TR_SEARCH);
t_ptr->name2 = SN_SEEING;
t_ptr->cost += 1000 + t_ptr->p1 * 100;
break;
case 6:
t_ptr->flags |= TR_REGEN;
rating += 10;
if (peek)
msg_print("Regeneration");
t_ptr->name2 = SN_REGENERATION;
t_ptr->cost += 1500;
break;
}
}
}
} else if (magik(cursed)) {
t_ptr->toac -= m_bonus(1, 20, level);
t_ptr->flags |= TR_CURSED;
t_ptr->cost = 0;
if (magik(special))
switch (randint(7)) {
case 1:
t_ptr->p1 = -randint(5);
t_ptr->flags |= TR_INT;
t_ptr->name2 = SN_STUPIDITY;
break;
case 2:
case 3:
t_ptr->p1 = -randint(5);
t_ptr->flags |= TR_WIS;
t_ptr->name2 = SN_DULLNESS;
break;
case 4:
case 5:
t_ptr->p1 = -randint(5);
t_ptr->flags |= TR_STR;
t_ptr->name2 = SN_WEAKNESS;
break;
case 6:
t_ptr->flags |= TR_TELEPORT;
t_ptr->name2 = SN_TELEPORTATION;
break;
case 7:
t_ptr->p1 = -randint(5);
t_ptr->flags |= TR_CHR;
t_ptr->name2 = SN_UGLINESS;
break;
}
}
break;
case TV_RING: /* Rings */
if (!((randint(10) == 1) && !not_unique && unique_armour(t_ptr))) {
switch (t_ptr->subval) {
case 0:
case 1:
case 2:
case 3: /* 132-135 */
if (magik(cursed)) {
t_ptr->p1 = -m_bonus(1, 10, level);
t_ptr->flags |= TR_CURSED;
t_ptr->cost = -t_ptr->cost;
} else {
t_ptr->p1 = m_bonus(1, 6, level);
t_ptr->cost += t_ptr->p1 * 100;
}
break;
case 4: /* 136 */
if (magik(cursed)) {
t_ptr->p1 = -randint(3);
t_ptr->flags |= TR_CURSED;
t_ptr->cost = -t_ptr->cost;
} else {
if (peek)
msg_print("Ring of Speed");
rating += 35;
if (randint(888) == 1)
t_ptr->p1 = 2;
else
t_ptr->p1 = 1;
}
break;
case 5:
t_ptr->p1 = 5 * m_bonus(1, 10, level);
t_ptr->cost += t_ptr->p1 * 30;
if (magik(cursed)) {
t_ptr->p1 = -t_ptr->p1;
t_ptr->flags |= TR_CURSED;
t_ptr->cost = -t_ptr->cost;
}
break;
case 14:
case 15:
case 16: /* Flames, Acid, Ice */
t_ptr->toac = m_bonus(1, 10, level);
t_ptr->toac += 5 + randint(7);
t_ptr->cost += t_ptr->toac * 100;
break;
case 17:
case 18: /* WOE, Stupidity */
t_ptr->toac = (-5) - m_bonus(1,10,level);
t_ptr->p1 = (-randint(4));
break;
case 19: /* Increase damage */
t_ptr->todam = m_bonus(1, 10, level);
t_ptr->todam += 3 + randint(10);
t_ptr->cost += t_ptr->todam * 100;
if (magik(cursed)) {
t_ptr->todam = -t_ptr->todam;
t_ptr->flags |= TR_CURSED;
t_ptr->cost = -t_ptr->cost;
}
break;
case 20: /* Increase To-Hit */
t_ptr->tohit = m_bonus(1, 10, level);
t_ptr->tohit += 3 + randint(10);
t_ptr->cost += t_ptr->tohit * 100;
if (magik(cursed)) {
t_ptr->tohit = -t_ptr->tohit;
t_ptr->flags |= TR_CURSED;
t_ptr->cost = -t_ptr->cost;
}
break;
case 21: /* Protection */
t_ptr->toac = m_bonus(0, 10, level);
t_ptr->toac += 4 + randint(5);
t_ptr->cost += t_ptr->toac * 100;
if (magik(cursed)) {
t_ptr->toac = -t_ptr->toac;
t_ptr->flags |= TR_CURSED;
t_ptr->cost = -t_ptr->cost;
}
break;
case 24:
case 25:
case 26:
case 27:
case 28:
case 29:
t_ptr->ident |= ID_NOSHOW_P1;
break;
case 30: /* Slaying */
t_ptr->ident |= ID_SHOW_HITDAM;
t_ptr->todam = m_bonus(1, 10, level);
t_ptr->todam += 2 + randint(3);
t_ptr->tohit = m_bonus(1, 10, level);
t_ptr->tohit += 2 + randint(3);
t_ptr->cost += (t_ptr->tohit + t_ptr->todam) * 100;
if (magik(cursed)) {
t_ptr->tohit = -t_ptr->tohit;
t_ptr->todam = -t_ptr->todam;
t_ptr->flags |= TR_CURSED;
t_ptr->cost = -t_ptr->cost;
}
break;
default:
break;
}
}
break;
case TV_AMULET: /* Amulets */
if (t_ptr->subval < 2) {
if (magik(cursed)) {
t_ptr->p1 = -m_bonus(1, 5, level);
t_ptr->flags |= TR_CURSED;
t_ptr->cost = -t_ptr->cost;
} else {
t_ptr->p1 = m_bonus(1, 5, level);
t_ptr->cost += t_ptr->p1 * 100;
}
} else if (t_ptr->subval == 2) { /* searching */
t_ptr->p1 = 5 * (randint(3) + m_bonus(0, 8, level));
if (magik(cursed)) {
t_ptr->p1 = -t_ptr->p1;
t_ptr->cost = -t_ptr->cost;
t_ptr->flags |= TR_CURSED;
} else
t_ptr->cost += 20 * t_ptr->p1;
} else if (t_ptr->subval == 8) {
rating += 25;
t_ptr->p1 = 5 * (randint(2) + m_bonus(0, 10, level));
t_ptr->toac = randint(4) + m_bonus(0, 8, level) - 2;
t_ptr->cost += 20 * t_ptr->p1 + 50 * t_ptr->toac;
if (t_ptr->toac < 0) /* sort-of cursed...just to be annoying -CWS */
t_ptr->flags |= TR_CURSED;
} else if (t_ptr->subval == 9) {
/* amulet of DOOM */
t_ptr->p1 = (-randint(5) - m_bonus(2, 10, level));
t_ptr->toac = (-randint(3) - m_bonus(0, 6, level));
t_ptr->flags |= TR_CURSED;
}
break;
/* Subval should be even for store, odd for dungeon */
/* Dungeon found ones will be partially charged */
case TV_LIGHT:
if ((t_ptr->subval % 2) == 1) {
t_ptr->p1 = randint(t_ptr->p1);
t_ptr->subval -= 1;
}
break;
case TV_WAND:
switch (t_ptr->subval) {
case 0:
t_ptr->p1 = randint(10) + 6;
break;
case 1:
t_ptr->p1 = randint(8) + 6;
break;
case 2:
t_ptr->p1 = randint(5) + 6;
break;
case 3:
t_ptr->p1 = randint(8) + 6;
break;
case 4:
t_ptr->p1 = randint(4) + 3;
break;
case 5:
t_ptr->p1 = randint(8) + 6;
break;
case 6:
t_ptr->p1 = randint(20) + 12;
break;
case 7:
t_ptr->p1 = randint(20) + 12;
break;
case 8:
t_ptr->p1 = randint(10) + 6;
break;
case 9:
t_ptr->p1 = randint(12) + 6;
break;
case 10:
t_ptr->p1 = randint(10) + 12;
break;
case 11:
t_ptr->p1 = randint(3) + 3;
break;
case 12:
t_ptr->p1 = randint(8) + 6;
break;
case 13:
t_ptr->p1 = randint(10) + 6;
break;
case 14:
t_ptr->p1 = randint(5) + 3;
break;
case 15:
t_ptr->p1 = randint(5) + 3;
break;
case 16:
t_ptr->p1 = randint(5) + 6;
break;
case 17:
t_ptr->p1 = randint(5) + 4;
break;
case 18:
t_ptr->p1 = randint(8) + 4;
break;
case 19:
t_ptr->p1 = randint(6) + 2;
break;
case 20:
t_ptr->p1 = randint(4) + 2;
break;
case 21:
t_ptr->p1 = randint(8) + 6;
break;
case 22:
t_ptr->p1 = randint(5) + 2;
break;
case 23:
t_ptr->p1 = randint(12) + 12;
break;
case 24:
t_ptr->p1 = randint(3) + 1;
break;
case 25:
t_ptr->p1 = randint(3) + 1;
break;
case 26:
t_ptr->p1 = randint(3) + 1;
break;
case 27:
t_ptr->p1 = randint(2) + 1;
break;
case 28:
t_ptr->p1 = randint(8) + 6;
break;
default:
break;
}
break;
case TV_STAFF:
switch (t_ptr->subval) {
case 0:
t_ptr->p1 = randint(20) + 12;
break;
case 1:
t_ptr->p1 = randint(8) + 6;
break;
case 2:
t_ptr->p1 = randint(5) + 6;
break;
case 3:
t_ptr->p1 = randint(20) + 12;
break;
case 4:
t_ptr->p1 = randint(15) + 6;
break;
case 5:
t_ptr->p1 = randint(4) + 5;
break;
case 6:
t_ptr->p1 = randint(5) + 3;
break;
case 7:
t_ptr->p1 = randint(3) + 1;
t_ptr->level = 10;
break;
case 8:
t_ptr->p1 = randint(3) + 1;
break;
case 9:
t_ptr->p1 = randint(5) + 6;
break;
case 10:
t_ptr->p1 = randint(10) + 12;
break;
case 11:
t_ptr->p1 = randint(5) + 6;
break;
case 12:
t_ptr->p1 = randint(5) + 6;
break;
case 13:
t_ptr->p1 = randint(5) + 6;
break;
case 14:
t_ptr->p1 = randint(10) + 12;
break;
case 15:
t_ptr->p1 = randint(3) + 4;
break;
case 16:
t_ptr->p1 = randint(5) + 6;
break;
case 17:
t_ptr->p1 = randint(5) + 6;
break;
case 18:
t_ptr->p1 = randint(3) + 4;
break;
case 19:
t_ptr->p1 = randint(10) + 12;
break;
case 20:
t_ptr->p1 = randint(3) + 4;
break;
case 21:
t_ptr->p1 = randint(3) + 4;
break;
case 22:
t_ptr->p1 = randint(10) + 6;
t_ptr->level = 5;
break;
case 23:
t_ptr->p1 = randint(2) + 1;
break;
case 24:
t_ptr->p1 = randint(3) + 1;
break;
case 25:
t_ptr->p1 = randint(2) + 2;
break;
case 26:
t_ptr->p1 = randint(15) + 5;
break;
case 27:
t_ptr->p1 = randint(2) + 2;
break;
case 28:
t_ptr->p1 = randint(5) + 5;
break;
case 29:
t_ptr->p1 = randint(2) + 1;
break;
case 30:
t_ptr->p1 = randint(6) + 2;
break;
default:
break;
}
break;
case TV_CLOAK:
if (magik(chance) || good) {
int made_art_cloak;
made_art_cloak = 0;
t_ptr->toac += 1 + m_bonus(0, 20, level);
if (magik(special) || (good == 666)) {
if (!not_unique &&
!stricmp(object_list[t_ptr->index].name, "& Cloak")
&& randint(10) == 1) {
switch (randint(9)) {
case 1:
case 2:
if (COLLUIN)
break;
if (wizard || peek)
msg_print("Colluin");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_COLLUIN;
t_ptr->toac = 15;
t_ptr->flags |= (TR_RES_FIRE | TR_RES_COLD | TR_POISON |
TR_RES_LIGHT | TR_RES_ACID);
t_ptr->flags2 |= (TR_ACTIVATE | TR_ARTIFACT);
t_ptr->cost = 10000L;
made_art_cloak = 1;
COLLUIN = 1;
break;
case 3:
case 4:
if (HOLCOLLETH)
break;
if (wizard || peek)
msg_print("Holcolleth");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_HOLCOLLETH;
t_ptr->toac = 4;
t_ptr->p1 = 2;
t_ptr->flags |= (TR_INT | TR_WIS | TR_STEALTH |
TR_RES_ACID);
t_ptr->flags2 |= (TR_ACTIVATE | TR_ARTIFACT);
t_ptr->ident |= ID_NOSHOW_TYPE;
t_ptr->cost = 13000L;
made_art_cloak = 1;
HOLCOLLETH = 1;
break;
case 5:
if (THINGOL)
break;
if (wizard || peek)
msg_print("Thingol");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_THINGOL;
t_ptr->toac = 18;
t_ptr->flags = (TR_DEX | TR_CHR | TR_RES_FIRE |
TR_RES_ACID | TR_RES_COLD | TR_FREE_ACT);
t_ptr->flags2 = (TR_ACTIVATE | TR_ARTIFACT);
t_ptr->p1 = 3;
t_ptr->cost = 35000L;
made_art_cloak = 1;
THINGOL = 1;
break;
case 6:
case 7:
if (THORONGIL)
break;
if (wizard || peek)
msg_print("Thorongil");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_THORONGIL;
t_ptr->toac = 10;
t_ptr->flags = (TR_SEE_INVIS | TR_FREE_ACT |
TR_RES_ACID);
t_ptr->flags2 |= (TR_ARTIFACT);
t_ptr->cost = 8000L;
made_art_cloak = 1;
THORONGIL = 1;
break;
case 8:
case 9:
if (COLANNON)
break;
if (wizard || peek)
msg_print("Colannon");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_COLANNON;
t_ptr->toac = 15;
t_ptr->flags |= (TR_STEALTH | TR_RES_ACID);
t_ptr->flags2 |= (TR_ACTIVATE | TR_ARTIFACT);
t_ptr->p1 = 3;
t_ptr->cost = 11000L;
made_art_cloak = 1;
COLANNON = 1;
break;
}
} else if (!not_unique &&
!stricmp(object_list[t_ptr->index].name,
"& Shadow Cloak")
&& randint(20) == 1) {
switch (randint(2)) {
case 1:
if (LUTHIEN)
break;
if (wizard || peek)
msg_print("Luthien");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_LUTHIEN;
t_ptr->toac = 20;
t_ptr->flags = (TR_RES_FIRE | TR_RES_COLD |
TR_INT | TR_WIS | TR_CHR | TR_RES_ACID);
t_ptr->flags2 = (TR_ACTIVATE | TR_ARTIFACT);
t_ptr->p1 = 2;
t_ptr->cost = 45000L;
made_art_cloak = 1;
LUTHIEN = 1;
break;
case 2:
if (TUOR)
break;
if (wizard || peek)
msg_print("Tuor");
else
good_item_flag = TRUE;
t_ptr->name2 = SN_TUOR;
t_ptr->toac = 12;
t_ptr->flags = (TR_STEALTH |
TR_FREE_ACT | TR_SEE_INVIS | TR_RES_ACID);
t_ptr->flags2 |= (TR_IM_ACID | TR_ARTIFACT);
t_ptr->p1 = 4;
t_ptr->cost = 35000L;
made_art_cloak = 1;
TUOR = 1;
break;
}
}
if (!made_art_cloak) {
if (randint(2) == 1) {
t_ptr->name2 = SN_PROTECTION;
t_ptr->toac += m_bonus(0, 10, level) + (5 + randint(3));
t_ptr->cost += 250L;
rating += 8;
} else if (randint(10) < 10) {
t_ptr->toac += m_bonus(3, 10, level);
t_ptr->p1 = randint(3);
t_ptr->flags |= TR_STEALTH;
t_ptr->name2 = SN_STEALTH;
t_ptr->cost += 500 + (50 * t_ptr->p1);
rating += 9;
} else {
t_ptr->toac += 10 + randint(10);
t_ptr->p1 = randint(3);
t_ptr->flags |= (TR_STEALTH | TR_RES_ACID);
t_ptr->name2 = SN_AMAN;
t_ptr->cost += 4000 + (100 * t_ptr->toac);
rating += 16;
}
}
}
} else if (magik(cursed)) {
tmp = randint(3);
if (tmp == 1) {
t_ptr->flags |= TR_AGGRAVATE;
t_ptr->name2 = SN_IRRITATION;
t_ptr->toac -= m_bonus(1, 10, level);
t_ptr->ident |= ID_SHOW_HITDAM;
t_ptr->tohit -= m_bonus(1, 10, level);
t_ptr->todam -= m_bonus(1, 10, level);
t_ptr->cost = 0;
} else if (tmp == 2) {
t_ptr->name2 = SN_VULNERABILITY;
t_ptr->toac -= m_bonus(10, 20, level + 50);
t_ptr->cost = 0;
} else {
t_ptr->name2 = SN_ENVELOPING;
t_ptr->toac -= m_bonus(1, 10, level);
t_ptr->ident |= ID_SHOW_HITDAM;
t_ptr->tohit -= m_bonus(2, 15, level + 10);
t_ptr->todam -= m_bonus(2, 15, level + 10);
t_ptr->cost = 0;
}
t_ptr->flags |= TR_CURSED;
}
break;
case TV_CHEST:
switch (randint(level + 4)) {
case 1:
t_ptr->flags = 0;
t_ptr->name2 = SN_EMPTY;
break;
case 2:
t_ptr->flags |= CH_LOCKED;
t_ptr->name2 = SN_LOCKED;
break;
case 3:
case 4:
t_ptr->flags |= (CH_LOSE_STR | CH_LOCKED);
t_ptr->name2 = SN_POISON_NEEDLE;
break;
case 5:
case 6:
t_ptr->flags |= (CH_POISON | CH_LOCKED);
t_ptr->name2 = SN_POISON_NEEDLE;
break;
case 7:
case 8:
case 9:
t_ptr->flags |= (CH_PARALYSED | CH_LOCKED);
t_ptr->name2 = SN_GAS_TRAP;
break;
case 10:
case 11:
t_ptr->flags |= (CH_EXPLODE | CH_LOCKED);
t_ptr->name2 = SN_EXPLOSION_DEVICE;
break;
case 12:
case 13:
case 14:
t_ptr->flags |= (CH_SUMMON | CH_LOCKED);
t_ptr->name2 = SN_SUMMONING_RUNES;
break;
case 15:
case 16:
case 17:
t_ptr->flags |= (CH_PARALYSED | CH_POISON | CH_LOSE_STR |
CH_LOCKED);
t_ptr->name2 = SN_MULTIPLE_TRAPS;
break;
default:
t_ptr->flags |= (CH_SUMMON | CH_EXPLODE | CH_LOCKED);
t_ptr->name2 = SN_MULTIPLE_TRAPS;
break;
}
if (not_unique) /* if bought from store - dbd */
t_ptr->p1 = randint(t_ptr->level);
else /* store the level chest's found on - dbd */
t_ptr->p1 = dun_level;
break;
case TV_SPIKE:
t_ptr->number = 0;
for (i = 0; i < 7; i++)
t_ptr->number += randint(6);
if (missile_ctr == MAX_SHORT)
missile_ctr = -MAX_SHORT - 1;
else
missile_ctr++;
t_ptr->p1 = missile_ctr;
break;
case TV_BOLT: case TV_ARROW: case TV_SLING_AMMO:
/* this fn makes ammo for player's missile weapon more common -CFT */
magic_ammo(t_ptr, good, chance, special, cursed, level);
break;
case TV_FOOD:
/* make sure all food rations have the same level */
if (t_ptr->subval == 90)
t_ptr->level = 0;
/* give all elvish waybread the same level */
else if (t_ptr->subval == 92)
t_ptr->level = 6;
break;
case TV_SCROLL1:
/* give all identify scrolls the same level */
if (t_ptr->subval == 67)
t_ptr->level = 1;
/* scroll of light */
else if (t_ptr->subval == 69)
t_ptr->level = 0;
/* scroll of trap detection */
else if (t_ptr->subval == 80)
t_ptr->level = 5;
/* scroll of door/stair location */
else if (t_ptr->subval == 81)
t_ptr->level = 5;
break;
case TV_POTION1: /* potions */
/* cure light */
if (t_ptr->subval == 76)
t_ptr->level = 0;
break;
default:
break;
}
}
static struct opt_desc {
const char *o_prompt;
int *o_var;
} options[] = {
{ "Running: cut known corners", &find_cut },
{ "Running: examine potential corners", &find_examine },
{ "Running: print self during run", &find_prself },
{ "Running: stop when map sector changes", &find_bound},
{ "Running: run through open doors", &find_ignore_doors},
{ "(g)et-key to pickup objects", &prompt_carry_flag},
{ "Prompt before pickup", &carry_query_flag},
{ "Rogue like commands", &rogue_like_commands},
{ "Show weights in inventory", &show_weight_flag},
{ "Show weights in equipment list", &show_equip_weight_flag},
{ "Highlight and notice mineral seams", &highlight_seams},
{ "Disable haggling in stores", &no_haggle_flag},
{ "Plain object descriptions", &plain_descriptions},
{ "Quick messages", &quick_messages},
{ "Equippy chars", &equippy_chars},
{ "Low hitpoint warning", &hitpoint_warn},
{ "Delay speed", &delay_spd},
{ (char *)0, (int *)0}
};
/* Set or unset various boolean options. -CJS- */
void
set_options()
{
register int i, max, ch;
vtype string;
prt(" ESC when finished, y/n or 0-9 to set options, <return> or - to move cursor",
0, 0);
for (max = 0; options[max].o_prompt != 0; max++) {
if (options[max].o_var == &hitpoint_warn)
(void)sprintf(string, "%-38s: %d0%% ", options[max].o_prompt,
*options[max].o_var);
else if (options[max].o_var == &delay_spd)
(void)sprintf(string, "%-38s: %d ", options[max].o_prompt,
*options[max].o_var);
else
(void)sprintf(string, "%-38s: %s ", options[max].o_prompt,
(*options[max].o_var ? "yes" : "no "));
prt(string, max + 1, 0);
}
erase_line(max + 1, 0);
i = 0;
for (;;) {
move_cursor(i + 1, 40);
ch = inkey();
switch (ch) {
case ESCAPE:
draw_cave();
creatures(FALSE); /* draw monsters */
prt_equippy_chars(); /* redraw equippy chars */
return;
case '-':
if (i > 0)
i--;
else
i = max - 1;
break;
case ' ':
case '\n':
case '\r':
if (i + 1 < max)
i++;
else
i = 0;
break;
case 'y':
case 'Y':
if ((options[i].o_var == &hitpoint_warn) ||
(options[i].o_var == &delay_spd))
bell();
else {
put_buffer("yes ", i + 1, 40);
*options[i].o_var = TRUE;
if (i + 1 < max)
i++;
else
i = 0;
}
break;
case 'n':
case 'N':
if (options[i].o_var == &delay_spd)
bell();
else if (options[i].o_var == &hitpoint_warn) {
put_buffer("00%", i + 1, 40);
*options[i].o_var = 0;
} else {
put_buffer("no ", i + 1, 40);
*options[i].o_var = FALSE;
if (i + 1 < max)
i++;
else
i = 0;
}
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '0':
if ((options[i].o_var != &delay_spd) &&
(options[i].o_var != &hitpoint_warn))
bell();
else {
ch = ch - '0';
*options[i].o_var = ch;
if (options[i].o_var == &hitpoint_warn)
sprintf(string, "%d0%% ", ch);
else
sprintf(string, "%d ", ch);
put_buffer(string, i + 1, 40);
if (i + 1 < max)
i++;
else
i = 0;
}
break;
default:
bell();
break;
}
}
}
static void
magic_ammo(t_ptr, good, chance, special, cursed, level)
inven_type *t_ptr;
int good, chance, special, cursed, level;
{
register inven_type *i_ptr = NULL;
register int i;
/* if wielding a bow as main/aux weapon, then ammo will be "right" ammo
* more often than not of the time -CFT */
if (inventory[INVEN_WIELD].tval == TV_BOW) i_ptr=&inventory[INVEN_WIELD];
else if (inventory[INVEN_AUX].tval == TV_BOW) i_ptr=&inventory[INVEN_AUX];
if (i_ptr && (randint(2)==1)){
if ((t_ptr->tval == TV_SLING_AMMO) &&
(i_ptr->subval >= 20) && (i_ptr->subval <= 21));
/* right type, do nothing */
else if ((t_ptr->tval == TV_ARROW) &&
(i_ptr->subval >= 1) && (i_ptr->subval <= 4));
/* right type, do nothing */
else if ((t_ptr->tval == TV_BOLT) &&
(i_ptr->subval >= 10) && (i_ptr->subval <= 12));
/* right type, do nothing */
else if ((i_ptr->subval >= 20) && (i_ptr->subval <= 21))
invcopy(t_ptr, 83); /* this should be treasure list index of shots -CFT */
else if ((i_ptr->subval >= 1) && (i_ptr->subval <= 4))
invcopy(t_ptr, 78); /* this should be index of arrows -CFT */
else /* xbow */
invcopy(t_ptr, 80); /* this should be index of bolts -CFT */
}
t_ptr->number = 0;
for (i = 0; i < 7; i++)
t_ptr->number += randint(6);
if (missile_ctr == MAX_SHORT)
missile_ctr = -MAX_SHORT - 1;
else
missile_ctr++;
t_ptr->p1 = missile_ctr;
/* always show tohit/todam values if identified */
t_ptr->ident |= ID_SHOW_HITDAM;
if (magik(chance)||good) {
t_ptr->tohit = randint(5) + m_bonus(1, 15, level);
t_ptr->todam = randint(5) + m_bonus(1, 15, level);
/* see comment for weapons */
if (magik(5*special/2)||(good==666))
switch(randint(11)) {
case 1: case 2: case 3:
t_ptr->name2 = SN_WOUNDING; /* swapped with slaying -CFT */
t_ptr->tohit += 5;
t_ptr->todam += 5;
t_ptr->damage[0] ++; /* added -CFT */
t_ptr->cost += 30;
rating += 5;
break;
case 4: case 5:
t_ptr->flags |= (TR_FLAME_TONGUE|TR_RES_FIRE); /* RF so won't burn */
t_ptr->tohit += 2;
t_ptr->todam += 4;
t_ptr->name2 = SN_FIRE;
t_ptr->cost += 25;
rating += 6;
break;
case 6: case 7:
t_ptr->flags |= TR_SLAY_EVIL;
t_ptr->tohit += 3;
t_ptr->todam += 3;
t_ptr->name2 = SN_SLAY_EVIL;
t_ptr->cost += 25;
rating += 7;
break;
case 8: case 9:
t_ptr->flags |= TR_SLAY_ANIMAL;
t_ptr->tohit += 2;
t_ptr->todam += 2;
t_ptr->name2 = SN_SLAY_ANIMAL;
t_ptr->cost += 30;
rating += 5;
break;
case 10:
t_ptr->flags |= TR_SLAY_DRAGON;
t_ptr->tohit += 3;
t_ptr->todam += 3;
t_ptr->name2 = SN_DRAGON_SLAYING;
t_ptr->cost += 35;
rating += 9;
break;
case 11:
t_ptr->tohit += 10; /* reduced because of dice bonus -CFT */
t_ptr->todam += 10;
t_ptr->name2 = SN_SLAYING; /* swapped w/ wounding -CFT */
t_ptr->damage[0] += 2; /* added -CFT */
t_ptr->cost += 45;
rating += 10;
break;
}
while (magik(special)) { /* added -CFT */
t_ptr->damage[0]++;
t_ptr->cost += t_ptr->damage[0]*5;
}
}
else if (magik(cursed)) {
t_ptr->tohit = (-randint(10)) - m_bonus(5, 25, level);
t_ptr->todam = (-randint(10)) - m_bonus(5, 25, level);
t_ptr->flags |= TR_CURSED;
t_ptr->cost = 0;
if (randint(5)==1) {
t_ptr->name2 = SN_BACKBITING;
t_ptr->tohit -= 20;
t_ptr->todam -= 20;
}
}
}